.7z 资源压缩
构建期可选把 html 资源目录打成单个 .7z(LZMA2),运行期启动整包解压到内存,浏览器请求查表直返。压缩对前端透明。
零外部 C++ 依赖——运行期解压用 vendored Igor Pavlov 7z Dec C SDK(third_party/7z-sdk/),cmake 自动建 h::7zdec 静态库,无 vcpkg、无 libarchive。
启用
安装构建期 Python 依赖(仅打包机需要,用户机无需):
bashpip install -r tools/requirements.txt # py7zr在窗口 Opts 设压缩力度(
#include "webview/compression.hpp"):cppwebview::Window::opts() .url(L"src/assets/html/index.html") .compression(webview::Compression::Max) // None / Fast / Normal / Max
力度档
| 枚举 | LZMA2 preset | 说明 |
|---|---|---|
Compression::None | — | 不压缩(默认,向后兼容,per-file RCDATA) |
Compression::Fast | 1 | 最快,压缩率低 |
Compression::Normal | 5 | 平衡 |
Compression::Max | 9 | 最慢,压缩率最高 |
机制
构建期:tools/gen_assets_rc.py 扫源码 Compression::X token。
- 非
None:py7zr 打assets.7z(LZMA2 preset),单条rASSET_7ZRT_RCDATA 嵌入,manifest 标mode=7z。 None:per-file RCDATA,mode=raw(向后兼容,旧工程不改动即默认行为)。
运行期:App 首次解析 manifest 后,若 mode=7z 用 vendored 7z Dec SDK 把 .7z 整包解压到内存 map(assetCache_,仅一次)。WebResourceRequested handler 按 manifest.mode 分流:
7z→ 查内存 map(key = archive 内相对路径)raw→ 按需读单条 RCDATA
体积收益
资源以 minified JS / CSS 为主时收益最大(LZMA2 对高重复 token 压比 4–6x)。整包压缩比 per-file 更强——跨文件字典吃重复 token。
代价:vendored 7z decoder 编译进 exe(~100–150KB LZMA 解码器)。净收益取决于资源占比——资源占 exe 越多,压缩越划算。
失败处理
| 场景 | 行为 |
|---|---|
mode=7z 但 rASSET_7Z 缺失 / 损坏 | App::init 弹错误框 + 退出 |
| 解压失败 | 同上 fatal exit |
| py7zr 构建期 import 失败 | Python sys.exit 提示 pip install -r tools/requirements.txt |
与资源打包的关系
压缩是打包的增强:opts.url 仍照常设,Compression::None 时退回标准 per-file 打包。两者地址模式、loadURL 三分支逻辑不变。