查看: 4145|回复: 3

鸿蒙冷启动优化:减少import、拆分HAR导出与HSP改HAR

[复制链接]
发表于 7 天前 | 显示全部楼层 |阅读模式
应用冷启动耗时并不只发生在首页渲染阶段。华为开发者联盟社区的一则实践案例指出,Application 和 Ability 初始化阶段包括资源加载、虚拟机创建、对象创建与初始化、依赖模块加载等环节,其中资源加载是最主要的耗时点。资源加载又可拆成三步:文件加载,即查找并解析文件并记录到模块中;依赖模块解析与实例化,为模块导出的变量分配内存空间;文件执行,运行 .ets 文件并把变量赋为真实值。围绕这条链路,案例给出了几项可直接落地的 ArkTS 工程优化手段。

一、减少 import 模块,优先使用系统模块并按需加载

应用执行代码前必须找到并加载所有导入的模块,每增加一个第三方框架或模块,都会增加启动时间,耗时取决于模块数量和大小。案例建议优先使用系统提供的模块,按需加载;对导入耗时较大的必要模块,可采用动态导入方式,官方文档中提供了 ArkTS 动态导入的说明。另一个容易忽略的点是嵌套的 export * 全量导出:冷启动时 HandleLaunchAbility 会执行相关 .ets 文件,主页面 import 的 .ets 文件都会被执行,包括数据结构、变量和全局函数的初始化。案例使用 Launch 分析对比了优化前嵌套 8 层 export * 与优化后直接从目标文件 import 的情况,分析阶段从开始加载 abc 文件(H:JSPandaFileExecutor::ExecuteFromAbcFile)到 abc 文件加载完成,优化后启动性能得到改善。

二、用按需引用替代 import * 全量引用

开发中常把相同类型的变量或函数集中到工具类文件,再通过 import 引入。当工具类暴露的函数或变量较多时,案例推荐按需引用具体变量,而不是使用 import * as nm 全量引用,以减少 .ets 文件执行耗时和所有 export 变量的初始化过程。案例对全量引用 2000 条数据与使用 import { One } 按需引用做了 Launch 对比,分析区间为 H:void OHOS::AppExecFwk::MainThread::HandleLaunchAbility(const std::shared_ptr &) 的开始点到结束点,优化后启动性能有提升。

三、拆分 HAR 导出文件,隔离非冷启动强相关文件

案例给出一个场景:应用包含首页 Index 和二级页面 SecondPage。首页展示 HAR 包中 MainPage.ets 的 Text 组件,该文件没有耗时操作;点击 Text 后跳转到二级页面,二级页面引用 HAR 包中的 SubPage.ets,而 SubPage.ets 包含在模块加载时执行的全局函数耗时操作。HAR 包的 Index.ets 同时导出 MainPage.ets 和 SubPage.ets,首页使用 import { MainPage } from 'library/Index' 导入时,冷启动过程会连带执行非冷启动强相关的 SubPage.ets,增加启动时间。

方案一是拆分 HAR 导出文件:新增 IndexAppStart.ets 仅导出首页相关文件 MainPage.ets,新增 IndexOthers.ets 导出非首页相关文件 SubPage.ets;首页从 IndexAppStart.ets 导入 MainPage,二级页面从 IndexOthers.ets 导入 SubPage。该方案能把冷启动阶段与非冷启动阶段需要执行的 .ets 文件完全拆开,但要求 IndexAppStart.ets 中的导出文件不能引用 IndexOthers.ets 中的导出文件。方案二是不新增文件,首页导入 MainPage.ets 时使用全路径,避免汇总导出把所有文件带进来;缺点是引用时要展开冷启动阶段所有文件路径,开发和维护成本更高。案例使用 Launch 分析优化前后性能,阶段起点为 UI Ability Launching,终点为应用首帧 First Frame - App Phase,两种方案均改善了启动表现。

四、减少多个 HAP/HSP 对相同 HAR 的引用

使用 HSP 或 HAR 共享包可以整合同类模块,在多个模块或工程间共享 ArkUI 组件、资源等代码。但案例提醒避免多个 HAP/HSP 引用相同 HAR,具体影响可参考官方模块化设计文档中“多 HAP/HSP 引用相同 HAR 包的影响”部分。

五、单 HAP 场景优先多 HAR,避免 HSP 额外加载开销

对于单窗口应用的 APP 工程,如果只包含一个 Entry 类型 HAP,且划分的模块没有按需加载需求,案例建议业务组件和公共组件采用 HAR 打包。最终构建 HAP 时,被依赖的 HAR 会编译进 HAP 包;HSP 采用动态加载,启动过程中会加载依赖的 HSP,带来额外 IO 与运行耗时。案例用 Launch 对比了 HAP 与 20 个 HSP 混合打包、以及把 20 个 HSP 设计成 HAR 包的启动性能,后者的启动表现更好。

整体来看,这组优化都围绕同一目标:缩短 Application 和 Ability 初始化阶段的资源加载与 .ets 执行时间。落地时可先用 Launch 分析定位模块加载和首帧阶段的时间分布,再按“减少 import 模块、避免嵌套 export *、按需引用、拆分 HAR 导出、控制 HAR/HSP 引用关系”的顺序逐项验证。案例也说明,这些手段需要结合具体模块划分和页面依赖关系取舍,例如拆分导出文件会带来额外维护约束,全路径导入则增加引用成本,适合在性能瓶颈明确后针对性实施。
回复

使用道具 举报

发表于 7 天前 | 显示全部楼层

Re: 鸿蒙冷启动优化:减少import、拆分HAR导出与HSP改HAR

这篇整理得很系统,把冷启动里资源加载和 .ets 执行这条链路拆得比较清楚,几个优化点也都比较能落地。尤其是嵌套 export * 和 import * 全量引用这两个,平时确实容易被忽略,很多时候不是业务逻辑慢,而是模块初始化阶段把不该执行的东西带进来了。HAR 导出拆分那两种方案也说得比较实在,拆文件能彻底隔离但会带来维护约束,全路径引用成本又高,确实要看瓶颈是否明确再动手。整体思路里“先用 Launch 定位模块加载和首帧时间分布,再逐项验证”这点很关键,避免为了优化而优化。还想请教一下,动态导入在实际工程里有没有什么容易踩坑的地方,比如对首屏依赖拆分粒度怎么把握比较合适。
回复 支持 反对

使用道具 举报

发表于 7 天前 | 显示全部楼层

Re: 鸿蒙冷启动优化:减少import、拆分HAR导出与HSP改HAR

看完很有启发,这篇把冷启动里资源加载和 .ets 文件执行这条链路拆得比较清楚,尤其是“嵌套 export * 会把非首页文件也带进来执行”和“拆分 HAR 导出隔离非冷启动强相关文件”这两点,很容易在实际工程里被忽略。减少 import、按需引用、单 HAP 场景优先多 HAR 这些手段也都给到了明确方向。 我个人比较认同先用 Launch 分析定位模块加载和首帧阶段的时间分布,再逐项验证,不然盲目拆包或改导入方式可能只增加维护成本。像拆分 HAR 导出文件虽然效果直接,但 IndexAppStart 不能引用 IndexOthers 这个约束在模块依赖变复杂时确实需要提前规划;全路径导入也一样,性能收益和引用成本要权衡。整体上这篇的落地顺序和取舍提醒都很实用。
回复 支持 反对

使用道具 举报

发表于 7 天前 | 显示全部楼层

Re: 鸿蒙冷启动优化:减少import、拆分HAR导出与HSP改HAR

看完挺有启发,尤其是把冷启动拆成资源加载三步来讲,比只说首页渲染更清楚。减少 import、避免嵌套 export * 和按需引用这几项门槛相对低,适合先排查。HAR 导出拆分那个例子很典型,首页只依赖 MainPage 却把 SubPage 带进来执行,确实容易踩;方案一约束明确,方案二全路径导入更直接但引用路径长。单 HAP 场景优先多 HAR、避免 HSP 额外加载开销这点也容易被忽略,不能为了模块化牺牲启动性能。实际落地还是得先用 Launch 看模块加载和首帧分布,再按顺序逐项验证,不然容易优化错地方。感谢分享。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-10-27 18:10 , Processed in 0.031399 second(s), 29 queries , Gzip On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部