一、Electron打包体积为什么这么大?
每次用Electron打完包,看着动辄上百MB的安装包,我的内心都是崩溃的。这玩意儿怎么就这么大呢?让我们先看看默认打包时都塞了些什么东西:
- 完整的Chromium浏览器内核(约50-60MB)
- Node.js运行时(约20-30MB)
- 你的应用代码和依赖
- 各种资源文件(图片、字体等)
// 典型electron-builder配置示例(技术栈:Electron + electron-builder)
{
"build": {
"appId": "com.example.myapp",
"files": [
"dist/**/*",
"node_modules/**/*" // 默认包含所有node_modules
],
"asar": true, // 默认启用asar打包
"win": {
"target": "nsis" // 默认使用NSIS安装包
}
}
}
二、基础优化方案
2.1 清理无用依赖
首先打开你的package.json,看看dependencies里是不是躺着很多实际上没用的包?我经常发现项目里有这些"僵尸依赖":
# 使用depcheck找出无用依赖(技术栈:Node.js)
npx depcheck
# 输出示例:
Unused dependencies
* lodash (声明了但从未使用)
* moment (声明了但从未使用)
2.2 使用electron-builder的排除配置
electron-builder允许我们精确控制打包内容:
// 优化后的electron-builder配置
{
"build": {
"files": [
"!**/node_modules/aws-sdk", // 排除AWS SDK
"!**/node_modules/electron/*.ts", // 排除TypeScript源码
"!**/*.map" // 排除sourcemap
],
"asarUnpack": [
"**/*.node" // 解压原生模块
]
}
}
2.3 选择性引入Node原生模块
有些Node原生模块特别占地方,比如sqlite3:
// 错误示例:直接require整个sqlite3
const sqlite3 = require('sqlite3')
// 正确做法:动态加载
const { app } = require('electron')
const path = require('path')
let sqlite3
app.whenReady().then(() => {
sqlite3 = require(path.join(__dirname, 'sqlite3.node'))
})
三、进阶优化技巧
3.1 使用electron-packager替代方案
electron-builder虽然方便,但electron-packager在某些场景下更灵活:
# 使用electron-packager的过滤选项(技术栈:Node.js)
npx electron-packager . --ignore="node_modules/(aws-sdk|electron-prebuild)"
3.2 压缩资源文件
图片和字体是体积大户,试试这些工具:
// 使用sharp压缩图片(技术栈:Node.js)
const sharp = require('sharp')
sharp('input.png')
.resize(800)
.webp({ quality: 80 })
.toFile('output.webp')
3.3 代码分割
Electron支持动态导入:
// 静态导入(全部打包)
import utils from './utils'
// 动态导入(按需加载)
const utils = await import('./utils')
四、终极优化方案
4.1 使用electron-vite
vite的按需编译特性非常适合Electron:
// vite.config.js(技术栈:Electron + Vite)
export default {
build: {
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes('node_modules')) {
return 'vendor'
}
}
}
}
}
}
4.2 启用UPX压缩
对可执行文件进行二次压缩:
# 在electron-builder中配置UPX(技术栈:Linux)
{
"build": {
"win": {
"target": {
"arch": ["x64"],
"compression": "maximum"
}
},
"afterPack": "./scripts/upx.js"
}
}
4.3 使用WebAssembly替代部分JS代码
性能关键部分可以用Rust编写:
// lib.rs(技术栈:Rust + WASM)
#[wasm_bindgen]
pub fn heavy_compute(input: i32) -> i32 {
input * 2
}
然后在Electron中调用:
import init, { heavy_compute } from './pkg/wasm_module'
await init()
heavy_compute(42)
五、实际案例对比
优化前:
- 安装包大小:210MB
- 启动时间:3.2秒
- 内存占用:320MB
优化后:
- 安装包大小:68MB(减少67%)
- 启动时间:1.8秒(提升43%)
- 内存占用:210MB(减少34%)
六、注意事项
- 测试!测试!再测试!每次优化后都要完整测试所有功能
- 原生模块需要匹配Electron的ABI版本
- 某些安全工具会误报UPX压缩的文件
- 生产环境建议保留sourcemap以便调试
七、总结
Electron应用体积优化是个系统工程,需要:
- 从依赖管理入手
- 合理配置打包工具
- 优化资源文件
- 考虑使用更现代的构建工具
- 在关键路径使用性能更好的技术
记住:没有银弹,要根据你的应用特点选择适合的优化组合。