HarmonyOS 7 API 26 包体积治理图

包体积问题通常不是某一次提交突然造成的,而是每次迭代都多一点资源、多一点依赖、多一点无用文件,最后安装包变得越来越重。上架前才发现包太大,再回头清理就很被动。

这篇按 HarmonyOS 7 / API 26 工程来拆包体积治理。重点不是“删文件”三个字,而是建立一套可复现的检查:哪些资源重复,哪些文件没有被引用,依赖带来了什么产物,构建前后体积变化是否超过阈值。

先把体积分成几类

类型 常见来源 处理方式
图片资源 多套重复截图、未压缩大图 压缩、按尺寸拆分、删除未引用
配置文件 老活动配置、测试 JSON 按环境隔离,不进 release
三方依赖 只用一个函数却引入整包 替换、拆 adapter、评估必要性
本地调试文件 mock、日志、临时导出 构建前拦截
重复代码产物 多模块重复打包 检查依赖边界

先分类,后面治理才不会变成到处乱删。

建一个构建产物快照

我会在每次 release 构建后记录一个体积快照。

~~~ts

type BundleFile = {

path: string

size: number

type: 'image' | 'config' | 'dependency' | 'code' | 'other'

}

type BundleSnapshot = {

buildNo: string

totalSize: number

files: BundleFile[]

}

function summarizeBundle(snapshot: BundleSnapshot): Record<string, number> {

return snapshot.files.reduce((sum, file) => {

sum[file.type] = (sum[file.type] || 0) + file.size

return sum

}, {} as Record<string, number>)

}

~~~

这个快照不一定要一开始就很复杂。先能统计总大小和分类大小,就能发现哪一类在涨。

案例一:图片重复导致体积慢慢涨

图片重复很常见。比如同一张示意图在不同目录放了两份,或者列表缩略图和详情图没有区分。

~~~ts

type ResourceHash = {

path: string

hash: string

size: number

}

function findDuplicatedResources(resources: ResourceHash[]): ResourceHash[][] {

const groups = new Map<string, ResourceHash[]>()

for (const item of resources) {

const list = groups.get(item.hash) || []

list.push(item)

groups.set(item.hash, list)

}

return Array.from(groups.values()).filter(list => list.length > 1)

}

~~~

输出重复文件后,不要马上删。先确认引用关系,再决定保留哪一份。

~~~ts

type ResourceUsage = {

path: string

referencedBy: string[]

}

function canRemoveResource(usage: ResourceUsage): boolean {

return usage.referencedBy.length === 0

}

~~~

这一步能避免误删。资源治理不是越狠越好,核心是删得有证据。

案例二:调试文件混进 release

第二类问题是 mock、测试 JSON、临时日志混进 release 包。

~~~ts

const forbiddenReleasePatterns = [

'/mock/',

'/debug/',

'sample-data',

'temp-export',

'.log'

]

function findForbiddenReleaseFiles(files: BundleFile[]): BundleFile[] {

return files.filter(file => {

return forbiddenReleasePatterns.some(pattern => file.path.includes(pattern))

})

}

~~~

这类检查适合放在 CI。只要 release 产物里出现这些路径,就直接失败。

~~~ts

function assertNoForbiddenFiles(files: BundleFile[]): void {

const forbidden = findForbiddenReleaseFiles(files)

if (forbidden.length === 0) {

console.info('[bundle-check] no forbidden files')

return

}

for (const file of forbidden) {

console.error('[bundle-check] forbidden file', file.path, file.size)

}

throw new Error('release bundle contains forbidden files')

}

~~~

对比构建前后变化

只看当前体积不够,要看和上一次相比涨了多少。

~~~ts

function diffSnapshot(before: BundleSnapshot, after: BundleSnapshot): { type: string, delta: number }[] {

const a = summarizeBundle(before)

const b = summarizeBundle(after)

const types = new Set([...Object.keys(a), ...Object.keys(b)])

return Array.from(types).map(type => ({

type,

delta: (b[type] || 0) - (a[type] || 0)

}))

}

function assertBundleDelta(before: BundleSnapshot, after: BundleSnapshot, limit: number): void {

const delta = after.totalSize - before.totalSize

if (delta > limit) {

throw new Error('bundle size increased too much: ' + delta)

}

}

~~~

阈值要根据项目定。比如普通迭代超过 500KB 就提示,超过 1MB 就阻断。大功能可以单独申请阈值,但要写明原因。

本地验证脚本

先造两份快照,看检查是否能跑通。

~~~ts

function verifyBundleCheck(): void {

const before: BundleSnapshot = {

buildNo: 'api26-001',

totalSize: 10_000_000,

files: [

{ path: '/resources/a.png', size: 300_000, type: 'image' },

{ path: '/src/main.abc', size: 2_000_000, type: 'code' }

]

}

const after: BundleSnapshot = {

buildNo: 'api26-002',

totalSize: 11_300_000,

files: [

{ path: '/resources/a.png', size: 300_000, type: 'image' },

{ path: '/resources/mock/sample-data.json', size: 800_000, type: 'config' },

{ path: '/src/main.abc', size: 2_100_000, type: 'code' }

]

}

console.info('[bundle-diff]', JSON.stringify(diffSnapshot(before, after)))

assertNoForbiddenFiles(after.files)

assertBundleDelta(before, after, 1_000_000)

}

~~~

预期结果是 sample-data.json 被拦住,总体积增长也会触发阈值。这样就能在 CI 阶段发现问题,而不是上架前靠人工翻目录。

包体积治理的取舍

做法 好处 风险
手动删大文件 容易漏,容易误删
每次构建生成快照 可追踪 需要维护脚本
CI 设置阈值 能阻断体积失控 大功能需要例外机制
资源 hash 去重 能发现重复文件 需要配合引用检查

我的选择是:快照加阈值作为基本盘,重复资源和禁用路径作为专项检查。这样成本不高,但能挡住大部分体积失控。

上架前检查清单

检查项 通过标准
release 产物 没有 mock、debug、临时日志文件
图片资源 没有明显重复 hash
体积变化 相比上一版本涨幅在阈值内
依赖变化 新依赖有用途说明
回归记录 产物快照随版本保存

小结

HarmonyOS 7 / API 26 包体积治理,要从构建产物出发,不要靠临时翻目录。先做快照,再查重复资源、禁用路径、依赖变化和体积阈值。这样安装包变大时,能知道是哪一类在涨,也能在 CI 阶段提前拦住。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐