我那个桌面应用,安装包 100M 起步,装完占 300M 上下。这个数字很多人第一次看到都会问一句怎么这么大。答案是 Chromium,但这不是不砍的理由。我砍过一轮,把能动的都动了,下面是我实际做了什么、哪些动的了、哪些动不了。
先量,别凭感觉砍
先说一个容易搞错的地方:安装包大小和解包后的大小是两回事。安装包是压缩过的,解包后才是真实占磁盘的体积,通常大 2 到 3 倍。两个数都要看,因为用户关心的是下载多久,你自己关心的是哪些文件在占地方。
量法很简单,安装包直接右键看属性,解包目录用命令行按大小列一遍:
# Windows 下按大小排,看谁占地方
powershell -Command "Get-ChildItem -Recurse -File | Sort-Object Length -Descending | Select-Object -First 20 Name, Length"
# 看 asar 里都打进去了什么
npx asar list resources/app.asar
不用装什么分析工具,这两个命令就够了。我第一次列出来的时候,前十个文件里有八个是 Chromium 的,剩下两个里有一个是我不认识的 dll。
到底是谁在占地方
| 部分 | 占多大 | 能不能动 |
|---|---|---|
| Chromium 内核(v8、icudtl.dat、ffmpeg.dll 等) | 解包后占大头 | 动不了 |
| locales 语言包 | 几十个语言,解包后十几 M 级别 | 能砍 |
| 原生模块(.node / .dll) | 看你用了几个 | 能砍 |
| 前端产物(js / css / 图片) | 看你写了多少 | 能砍 |
| LICENSE、CHANGELOG、测试文件 | 几 M,零碎 | 能砍 |
能砍的五项,按收益排序
1. locales:只留两个语言
这一项收益最大,也最省事。Electron 默认把几十个语言的 pak 文件全打进去,你一个中文软件,用户 99% 用不到冰岛语和斯瓦希里语。只留 zh-CN 和 en-US,其余删掉。
electron-builder 里这样写:
"electronLanguages": ["zh-CN", "en-US"]
注意这一项要写在 build 配置的顶层,不是塞进 win 里。写错了不报错,就是不生效,很容易白干。
2. 多余资源文件
LICENSE.electron.txt、LICENSES.chromium.html 这些可以删,几 M 的量,不影响运行。前端产物里的 sourcemap 一定要排除,它只对线上调试有用,你发的是桌面版,用户打开开发者工具看到源码也没意义。
"files": [
"!**/*.map",
"!**/LICENSE*",
"!**/*.md",
"!**/test/**"
]
3. 前端产物本身
这一项容易被忽略。我之前把一个中文字体整个打进去,光字体就十几 M,后来换成按需子集,只剩几百 K。图片同理,一张没压缩的截图能顶几十个 js 文件。
查法是用构建产物的体积分析,vite 和 webpack 都自带,看哪几个包最大,先动那几个。
4. 原生模块:只打目标架构,用到才加载
如果你的应用用了 koffi、better-sqlite3 这类原生模块,它们自带多平台多架构的文件。只发 Windows x64 的话,其他全都别打进去。
还有一点,原生模块不要在主进程启动时就 require。我那个调 Windows API 的库就是懒加载的,用户不用那个功能,那个 dll 就不会被加载。这不只是省内存,也让启动路径上少一个可能失败的东西,白屏的概率会小很多。
5. 压缩方式
NSIS 默认的压缩算法可以换成 lzma,体积能再小一点,代价是安装时解压慢几秒。用户下载快一点、装的时候多等两秒,我觉得值。
"nsis": {
"compression": "maximum"
}
砍不掉的三样
说完能砍的,说砍不掉的,免得你在这上面浪费时间。
第一是 Chromium 本体。它占你安装包的绝大多数,v8 引擎、渲染器、网络栈、各种 dll,一个都拆不下来。你就算把应用代码删光,只留个空白窗口,安装包照样有七八十 M。
第二是 asar。很多人以为打成 asar 就压缩了,其实它只是把文件打成一个归档,方便一次性读,体积一点没减。想减体积只能靠删除和压缩,asar 本身不干这事。
第三是编解码相关的库,比如 ffmpeg.dll。你的应用就算不播视频,它也在,因为 Chromium 的媒体管线依赖它。删掉的后果是某些网站上的音视频放不出来,我试过,不值当。
我不做的事
有两条线我不碰。
一条是为了省 10M 砍功能。比如把某个不常用的模块整个去掉,或者把界面里的图标换成字符。用户感觉不到安装包小了 10M,但能感觉到功能没了。
另一条是把整个 node_modules 打进去。有些人图省事不排除 devDependencies,结果安装包里塞了一堆构建工具,几十 M 就这么进去了,运行的时候一次都用不到。
真实情况是:Electron 的安装包下限就在七八十 M,你能优化的空间大概几十 M。想真正做到十几 M,得换 WebView2 或者 Tauri 那套,代价是渲染一致性和原生能力的填充工作。这个账我在另一篇里算过,这里不重复。