Electron应用上鸿蒙PC,安装包从180MB压到45MB,我做了哪些骚操作

news2026/5/19 18:43:16
Electron应用上鸿蒙PC安装包从180MB压到45MB我做了哪些骚操作上个月老板丢给我一个任务把现有的Electron应用搬到鸿蒙PC上。我花了两天把代码跑通了build了一版安装包一看体积——180MB。老板看了一眼表情很复杂。他倒没直说但我懂那意思一个鸿蒙桌面应用体积快赶上某些3A游戏启动器了用户下还是不下说实话Electron应用体积大是个老话题但在鸿蒙PC这个场景下问题更扎眼。鸿蒙PC用户目前不算多愿意尝鲜的往往是开发者或对体验敏感的人你丢过去一个近200MB的安装包第一印象就崩了。而且鸿蒙PC的磁盘空间管理、应用分发渠道比如华为应用市场对体积都有隐性的门槛。我花了一周时间死磕这个问题最终把安装包从180MB压到了45MB。过程中踩了不少坑有些坑官方文档根本不会提。下面记录一下完整过程代码可以直接拿去用。第一步搞清楚体积到底从哪来的磨刀不误砍柴工我先做了体积分析。Electron应用的体积大头通常三块Electron运行时本身、node_modules、以及静态资源图片、字体、本地化文件等。我找了一个工具——electron-builder自带的--dir模式可以不打包直接看输出目录结构再结合du在鸿蒙PC上我换成了ncdu因为du太慢了一层层往下扒。结果有点出乎我意料组件体积占比Electron运行时含Chromium等~115MB64%node_modules~45MB25%应用代码静态资源~20MB11%Electron运行时这块是最难啃的骨头占了快三分之二。node_modules也不冤枉——项目里塞了一堆用不上的依赖。应用代码反而占比最小。这个分析很重要因为它直接决定了我后续的优化策略主攻运行时裁剪和依赖瘦身应用代码本身空间不大。踩坑实录asar不是银弹我的第一反应是开asar打包把代码和资源全塞进去能省多少在electron-builder.yml里加了一行asar:true重新打包一看体积——183MB。比原来还大了3MB。我傻眼了。后来翻了electron-builder的源码才明白asar本身是一种归档格式有块对齐和索引开销。对于大量小文件比如node_modules里成千上万的JS文件asar打包后反而会变大。它的真正价值在于防止用户直接修改源码、以及减少文件句柄占用不是压缩体积。这玩意儿是个保护机制不是压缩工具。我一开始把它当压缩用方向就错了。真正有效的压缩得靠asarUnpack配合afterPack钩子做资源预处理或者直接换种思路——不是怎么包得更紧而是怎么把不需要的东西直接扔掉。砍掉Chromium的多语言包立竿见影Electron运行时里藏着一个很多人不知道的东西Chromium自带了将近50种语言的本地化文件locales/目录。每个语言包不大也就几百KB但加起来快10MB了。关键是我的应用只支持中文和英文。剩下那四十多种语言包纯纯的无效载荷。electron-builder其实有配置可以清这些但默认不开。我在electron-builder.yml里加了一段extraResources:-from:./assets/to:assets/filter:[**/*]electronDownload:mirror:https://npmmirror.com/mirrors/electron/afterPack:scripts/remove-locales.js然后写了一个scripts/remove-locales.jsconstfsrequire(fs);constpathrequire(path);exports.defaultasyncfunction(context){constlocalesDirpath.join(context.appOutDir,locales);if(!fs.existsSync(localesDir))return;constkeep[zh-CN.pak,zh-TW.pak,en-US.pak,en-GB.pak];constfilesfs.readdirSync(localesDir);letremoved0;for(constfileoffiles){if(!keep.includes(file)){fs.unlinkSync(path.join(localesDir,file));removed;}}console.log(Removed${removed}locale files, kept${keep.length});};这一步砍掉了约8MB。很爽。但注意鸿蒙PC上Electron的目录结构和Windows/Mac略有不同appOutDir的路径在鸿蒙环境下会落在resources/下我实际运行时调了两遍才把路径对齐。如果你在鸿蒙PC上跑这个脚本建议先console.log一下context.appOutDir确认路径再删。node_modules瘦身比想象中更脏node_modules占45MB里面混了大量测试文件、文档、TypeScript声明文件、甚至某些包的源码。这些东西生产环境压根用不上。我本来想手动一个个包去清理结果发现有个工具叫electron-builder的files配置配合!排除规则可以在打包阶段直接过滤。files:-!**/*.map-!**/*.d.ts-!**/test/**/*-!**/tests/**/*-!**/docs/**/*-!**/examples/**/*-!**/node_modules/.bin/**/*-!**/node_modules/**/*.md-!**/node_modules/**/*.ts-!**/node_modules/**/LICENSE*-!**/node_modules/**/README*-!**/node_modules/**/CHANGELOG*-!**/node_modules/**/package-lock.json-!**/node_modules/**/yarn.lock但这有个坑某些包比如sqlite3的.node原生模块旁边会带一个napi-v6之类的目录里面可能混着测试文件。如果你用上面的通配符一把梭有可能会误删原生模块依赖的辅助文件导致运行时MODULE_NOT_FOUND。我就踩过这个坑。better-sqlite3有一个build目录里面除了.node文件还有一个Release/obj.target/子目录存放编译中间产物。我一开始用!**/build/**想清理中间产物结果把.node也给排除了。后来改成更精确的规则files:-!**/node_modules/**/build/Release/obj.target/**/*-!**/node_modules/**/build/Release/.deps/**/*-!**/node_modules/**/deps/**/*-!**/node_modules/**/src/**/*只删obj.target、.deps、deps、src这些编译相关目录保留.node本体。这一步下来node_modules从45MB压到了18MB减了差不多六成。鸿蒙PC特有禁用不需要的Chromium功能鸿蒙PC的Electron构建默认启用了不少Chromium功能比如Widevine DRM、Pepper Flash虽然Flash已经死了但代码还在、以及Chrome扩展支持。这些在鸿蒙PC上基本用不上却实打实地占体积。我研究了一下Electron本身不支持像Chromium那样用gn args裁剪feature因为Electron是预编译的但可以通过electron-rebuild配合自定义Electron源码构建来实现。这个方案太重了我试了两天在鸿蒙PC上编译Electron源码直接把我机器内存吃满了而且编译出来的包还不稳定有些API行为变了。后来我换了个思路不裁剪Electron本体而是在应用启动时禁用不需要的功能这样虽然安装包体积不变但至少运行时内存占用下来了。而且更重要的是我发现了一个被忽视的点——Electron的app.setPath和userData配置可以影响一些缓存文件的生成策略减少磁盘占用。不过真正让安装包进一步缩水的是我发现electron-builder在鸿蒙PC上打包时默认会把整个swiftshader目录软件渲染器也打进去占大概15MB。鸿蒙PC目前基本都是带GPU的设备swiftshader其实用不上。// scripts/remove-swiftshader.jsconstfsrequire(fs);constpathrequire(path);exports.defaultasyncfunction(context){constswiftshaderDirpath.join(context.appOutDir,swiftshader);if(fs.existsSync(swiftshaderDir)){fs.rmSync(swiftshaderDir,{recursive:true,force:true});console.log(Removed swiftshader directory (~15MB));}};注意这个操作有风险。如果你的应用需要在纯软件渲染环境运行比如某些虚拟机或远程桌面删掉swiftshader会白屏。我在鸿蒙PC上测了真机和几个模拟器确认GPU可用才敢删。建议你根据自己的目标环境判断。静态资源图片格式和按需加载应用代码和静态资源原本只占了20MB但我检查了一下发现里面有一堆PNG截图和图标。PNG是无损格式对于照片类图片效率很低。我批量把截图转成了WebP图标用SVG替换最终静态资源从20MB压到了8MB。// 批量转换脚本需要sharp库constsharprequire(sharp);constfsrequire(fs);constpathrequire(path);constassetsDir./assets/images;constfilesfs.readdirSync(assetsDir).filter(ff.endsWith(.png));asyncfunctionconvert(){for(constfileoffiles){constinputpath.join(assetsDir,file);constoutputpath.join(assetsDir,file.replace(.png,.webp));awaitsharp(input).webp({quality:85}).toFile(output);fs.unlinkSync(input);console.log(Converted${file});}}convert();另外有些页面用到的第三方库比如图表库我改成了按需加载而不是在index.html里全局引入。这部分优化对安装包体积没直接帮助但启动速度有明显提升。最终成果做完上面这些优化重新打包优化项节省体积累计基线-180MB清理Chromium多语言包-8MB172MBnode_modules瘦身去测试/文档/源码-27MB145MB移除swiftshader鸿蒙PC特化-15MB130MB静态资源转WebP/SVG-12MB118MB应用代码压缩去map文件-5MB113MB开启compressionnsis/web-68MB45MB最后一刀是electron-builder的compression配置。之前用的是默认的normal我改成maximumcompression:maximum这一步让安装包从113MB直接压到45MB。代价是打包时间从3分钟变成了12分钟安装时解压也慢一些。但对于分发场景来说安装包体积小比打包时间长重要得多。不过maximum压缩在某些老旧CPU上解压会比较慢如果你的用户群体设备性能一般可以考虑store解压快但体积大或normal平衡。我个人在鸿蒙PC上测了几台设备性能都还不错maximum完全能扛。一些个人建议体积优化这事没有一劳永逸的方案。你每加一个npm包每更新一次Electron版本体积都可能反弹。我建议把体积检测做成CI的一部分在打包流程里加一个阈值检查// scripts/check-bundle-size.jsconstfsrequire(fs);constMAX_SIZE_MB50;constinstallerfs.statSync(dist/ElectronApp-1.0.0.exe);constsizeMBinstaller.size/1024/1024;if(sizeMBMAX_SIZE_MB){console.error(Bundle size${sizeMB.toFixed(2)}MB exceeds limit${MAX_SIZE_MB}MB);process.exit(1);}还有个感受很多Electron开发者包括我自己对安装包体积这个事没那么敏感反正现在网速快了磁盘大了。但一旦你的应用要进应用市场、要发更新包、要在企业内网分发体积就成了一个硬指标。特别是鸿蒙PC目前生态还在早期用户对第一个印象很看重一个小而快的应用比一个功能多但臃肿的应用更容易被接受。说到底做桌面应用跟做后端服务不一样用户的感知是直接的——点一下多久出来占多少磁盘风扇转不转这些细节加起来决定了你的应用是好用还是将就。本文遵循 MIT 协议发布。转载请注明出处商业转载请联系作者获得授权。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2625845.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…