求助:Electron Builder应用安装更新后启动耗时过长如何优化?
Electron应用更新后重启耗时过长的解决方案
问题描述
我开发的基于Angular的Electron应用,以NSIS作为Windows打包目标、S3为发布源,正常启动仅需2秒。但调用autoUpdater.quitAndInstall(true,true)完成更新后,应用关闭再重启耗时约50秒,远长于手动卸载重装的耗时,严重影响用户体验,现寻求缩短该耗时的解决方案。
package.json配置
{ "name": "MyApp", "version": "1.0.0", "description": "My application", "author": "Author", "license": "ISC", "productName": "MyApp", "main": "main.js", "build": { "appId": "com.MyApp.DesktopApp", "asar": true, "win": { "target": [ { "target": "nsis", "arch": [ "x64" ] } ], "icon": "assets/desktop-app-logo.ico" }, "nsis": { "installerIcon": "assets/logo-accent.ico", "uninstallerIcon": "assets/logo-accent.ico", "uninstallDisplayName": "MyApp", "oneClick": false, "artifactName": "MyApp-Setup-${version}.${ext}", "allowToChangeInstallationDirectory": true, "deleteAppDataOnUninstall": true }, "files": [ "*.*", "**/*", "node_modules/electron-updater/**/*", "node_modules/builder-util-runtime/**/*", "node_modules/graceful-fs/**/*", "node_modules/lazy-val/**/*", "node_modules/lodash.escaperegexp/**/*", "node_modules/lodash.isequal/**/*", "node_modules/sax/**/*", "node_modules/argparse/**/*", "node_modules/debug/**/*", "node_modules/fs-extra/**/*", "node_modules/jsonfile/**/*", "node_modules/js-yaml/**/*", "node_modules/lodash.escaperegexp/**/*", "node_modules/lodash.isequal/**/*", "node_modules/lru-cache/**/*", "node_modules/ms/**/*", "node_modules/rxjs/**/*", "node_modules/semver/**/*", "node_modules/tslib/**/*", "node_modules/typed-emitter/**/*", "node_modules/universalify/**/*", "node_modules/yallist/**/*", "node_modules/electron-log/**/*", "!**/node_modules/*/{CHANGELOG.md,README.md,README,readme.md,readme}", "!**/node_modules/*/{test,__tests__,tests,powered-test,example,examples}", "!**/node_modules/*.d.ts" ], "directories": { "output": "../installer" }, "publish": { "provider": "s3", "bucket": "myBucket", "path": "desktop-repo", "region": "eu-west-1", "endpoint": "https://s3.eu-west-1.amazonaws.com" } }, "dependencies": { "electron-updater": "6.1.1", "electron-log": "4.4.8" }, "devDependencies": { "electron": "22.0.0", "electron-builder": "24.6.3" }, "scripts": { "electron-installer-build": "electron-builder", "electron-installer-publish": "electron-builder -p always" } }
注:files参数中的长文件列表是为了将electron builder及其依赖复制到应用打包目录
main.js中的更新逻辑代码
autoUpdater.on('error', (error) => { dialog.showErrorBox('Error: ', error == null ? "unknown" : (error.stack || error).toString()) }) autoUpdater.on('update-available', () => { dialog.showMessageBox({ type: 'info', title: 'Found Updates', message: 'Found updates, do you want update now?', buttons: ['Sure', 'No'] }).then((buttonIndex) => { if (buttonIndex === 0) { autoUpdater.downloadUpdate() } else { updater.enabled = true updater = null } }) }) autoUpdater.on('update-not-available', () => { dialog.showMessageBox({ title: 'No Updates', message: 'Current version is up-to-date.' }) updater.enabled = true updater = null }) autoUpdater.on('update-downloaded', () => { dialog.showMessageBox({ title: 'Install Updates', message: 'Updates downloaded, application will be quit for update...' }).then(() => { autoUpdater.quitAndInstall(true, true) }) })
解决方案
1. 优化NSIS更新流程
当前配置oneClick: false(非一键安装),autoUpdater更新时会执行完整的卸载+安装流程,而手动重装是直接覆盖安装,跳过了部分卸载环节:
- 若无需自定义安装路径,可将
oneClick改为true,NSIS一键更新的流程更轻量化,减少卸载步骤的耗时; - 若必须保留自定义路径,可编写自定义NSIS脚本,简化更新时的卸载逻辑:比如跳过注册表清理、不必要的文件校验,仅替换应用核心文件。
2. 调整quitAndInstall参数
你当前使用autoUpdater.quitAndInstall(true, true),第二个参数isSilent设为true可能导致安装程序在后台执行冗余的等待或校验逻辑:
- 尝试改为
autoUpdater.quitAndInstall(false, false),让安装程序以交互模式运行,避免后台无意义等待; - 或仅调整第二个参数为
false,保留强制重启的同时,让安装流程更透明。
3. 简化files配置,避免冗余文件处理
你手动指定了大量electron-updater相关依赖,可能导致更新时重复校验、解压这些文件。electron-builder会自动处理打包所需的依赖,无需手动添加:
- 删除files列表中
node_modules/electron-updater/**/*及相关依赖的手动配置,仅保留必要的排除规则,让builder自动管理依赖。
4. 启用差分更新
electron-builder支持差分更新(Delta Updates),仅下载版本间的差异文件,大幅减少安装时的文件操作量:
- 在
publish配置中添加"generateUpdatesFilesForAllChannels": true,开启差分更新包生成; - 你的
electron-updater@6.1.1版本已支持差分更新,启用后更新时无需替换所有文件,能显著缩短安装耗时。
5. 排查更新后首次启动的瓶颈
更新后首次启动慢,可能是应用在第一次启动时执行了初始化操作(如数据库迁移、缓存重建),或系统需要缓存新文件:
- 在main.js中添加日志,记录从启动到窗口显示的各个阶段耗时(如
app.on('ready')触发时间、窗口加载完成时间),定位具体拖慢的环节; - 若为应用初始化逻辑导致,可将这些操作异步执行或延迟到窗口显示后再处理。
内容的提问来源于stack exchange,提问作者Franco
相关产品推荐
相关产品推荐

