包体积从 90MB 压到 45MB,HSP 和 so 压缩只是第一刀
应用上架前的包体积检查,90MB 的 HAP 摆在面前。你打开分析工具一看,libs 目录下 arm64-v8a 和 armeabi-v7a 各躺着一套 so,resources 里一堆重复的图片,多个 HAR 模块里同一份工具库被拷贝了好几遍。
HarmonyOS 应用的包体积优化不是“压缩一下”这么简单,它是一条从架构筛选到 Native 压缩再到资源去重的流水线。先搞清楚体积花在哪里,再决定砍哪里。

so 库压缩是一行配置的事
DevEco Studio 默认打包时不压缩 so 库。在 module.json5 里把 compressNativeLibs 设为 true,重新打包,so 会以压缩形式进包。以 C++ 默认库为例,libc++_shared.so 从 1108KB 压到 386KB,压缩率约 34%。
json5
{
"module": {
"compressNativeLibs": true
}
}
这个配置只影响打包方式,不影响运行时加载。应用启动时系统会自动解压 so 到内存或临时目录,开发者不需要额外处理。唯一的代价是首次加载多了一次解压动作,对启动时间的影响通常在毫秒级。
HAR 重复拷贝用 HSP 消除
多个 HAP 或者 HAR 共享同一份代码和资源时,HAR 是静态共享包,每个引用它的模块产物里都会各拷一份。HSP 是动态共享包,运行时多模块共享同一份,包里只存一份。
判断标准很简单:同一个依赖被三个以上模块引用,并且体积可观,就值得从 HAR 迁到 HSP。迁移本身是配置变更:模块的 module.json5 里 type 改为 shared,deliveryWithInstall 根据是否需要随安装包分发来设置,使用方的 oh-package.json5 依赖方式对应调整。
json5
// HSP 模块的 module.json5
{
"module": {
"name": "common_ui",
"type": "shared",
"deliveryWithInstall": true
}
}
deliveryWithInstall: true 表示 HSP 随应用一起安装,适合大多数共享组件库。设为 false 表示按需加载,用户首次用到时才下载,适合低频功能模块。
HSP 不是没有代价。大量使用 HSP 替代 HAR 会增加编译耗时和内存占用,因为编译引用这些 HSP 的模块时会触发更多的语言编译任务。小体积、低复用的模块继续用 HAR 更划算,不要为了“架构统一”把一切都塞进 HSP。
架构筛选和依赖冲突去重
arm64-v8a 是当前 HarmonyOS 设备的主力架构,armeabi-v7a 只在极老的设备上需要。如果应用没有明确的 32 位设备覆盖要求,只保留 arm64-v8a,so 体积直接减半。
依赖冲突是另一块隐形肥肉。不同三方库依赖同一个基础库的不同版本时,ohpm 可能把多个版本都打进来。用 override 机制强制统一版本,或者开启 resolve_conflict 让 ohpm 按规则合并,能消掉一批重复编译产物。
json5
// oh-package.json5
{
"overrides": {
"@ohos/common_utils": "1.2.0"
}
}
overrides 把所有传递依赖里的 common_utils 统一拉到指定版本,避免多版本共存。改完之后跑一次依赖树分析,确认没有其他库锁死在旧版本上。

包体积优化的顺序应该是先扫描、再砍架构、然后 so 压缩、最后 HSP 去重。扫描工具告诉你钱花在哪里,架构筛选和 so 压缩是确定性的收益,HSP 去重收益大但有编译代价。把最容易的一刀先砍下去,再看剩下的体积分布决定要不要动 HSP。90MB 到 45MB 的差距里,so 架构筛选加压缩通常贡献一半,HAR 去重贡献另一半,两者缺一不可。
更多推荐
所有评论(0)