专栏名称: InfoQ
有内容的技术社区媒体。
目录
相关文章推荐
新浪科技  ·  【存5万元送一个盲盒,银行也靠LABUBU拉 ... ·  19 小时前  
新浪科技  ·  【#王自如AI领域重新创业#】@王自如AI ... ·  2 天前  
51好读  ›  专栏  ›  InfoQ

小红书鸿蒙 OS 下的性能优化探索与实践

InfoQ  · 公众号  · 科技媒体  · 2025-04-08 16:00

正文

请到「今天看啥」查看全文


我们开发了一个“一多框架”,这是一个支持一套代码多端部署的具体框架体系。通过这个框架,我们实现了多设备的断点控制功能。用户可以根据设备的尺寸和类型进行适配,因为华为设备支持多端投屏。例如,用户可以在手机上浏览小红书,然后将内容投屏到车机上。比如用户购买了一辆问界汽车,可以在车内通过车机继续浏览手机上的小红书内容,这种场景在驾驶时尤其有用。

除了底层框架,对于上层业务,小红书还有一套自研的组件库方案,这套组件库承载了上层业务的多种功能,包括图文笔记、视频笔记浏览,以及一些 Hybrid 容器能力。小红书本质上在跨端开发中仍然使用了 React Native(RN)和类 Web 技术。RN 引擎由华为内部合作提供,采用了自研的 ohos 方案,用于解决 React Native 的 bundle 和 JS 加载以及渲染问题。此外,还包括产品定制层,这里涵盖了所有相关的设备适配内容。

性能优化与实践

目前,安卓和 iOS 在性能优化方面已经相当成熟,包括如何分析性能热点问题、有哪些工具以及最佳实践等。然而,对于鸿蒙来说,它是一个全新的系统。直到 2024 年年中,鸿蒙的稳定性和流畅性都还存在一些问题。这里重点讲述小红书在 2024 年与华为一起进行了哪些实践,以提升应用的性能和用户体验。

我们定义了一个性能指标场景。这个指标体系是小红书与华为共同探讨的结果,因为华为有一个性能工厂,它对每个应用的评级都有一个 S 标标准。小红书与华为一起确定了针对小红书场景需要观测的具体指标。性能优化的核心是慢函数指标,它主要包含两部分:过程时长和应用体验的流畅性。

过程时长主要包含以下三点:

  1. 冷启动时长 :这是用户最关心的指标之一,即从点击应用图标到应用完成动画并展示第一帧的时间。对于多数应用,首页通常有缓存机制。例如,小红书会缓存用户上次刷新的笔记,淘宝会缓存用户上次浏览的商品内容。

  2. 场景完成时长 :指完成某个特定场景所需的时间。

  3. 应用响应时长 :指用户操作界面后,界面真正发生变化的时间,即响应时延。

流畅性方面,最基础的观测指标是平均 FPS(帧率),包括丢帧数、最大连续丢帧数、丢帧卡顿次数以及卡顿率。卡顿率可以通过量化计算得出:当一个场景中出现丢帧时,丢帧的时长与场景总时长的比值即为卡顿率,它是一个小于 1 的百分比数值。

OS 能力 & 优化实践

首先,针对 IO 场景,我们进行了相应的优化。鸿蒙 OS 的系统能力主要分为以下三个方面:

  1. 并行化能力 鸿蒙 OS 提供了两种并行化能力:Worker 和 TaskPool。Worker 类似于传统的线程模型,每个 Worker 都有自己的内存空间和执行单元,支持通过消息(message)进行通信。TaskPool 则类似于协程或线程池,能够动态管理线程数量,支持标记为 @concurrent 的函数直接在任务池中调度和运行。这两种机制都支持线程间隔离,内存不共享。

  2. 多线程通信和数据传输 在多线程通信方面,鸿蒙 OS 支持序列化数据传输和基于消息(message)的通信机制。此外,还引入了事件发射器(Emitter)用于系统事件的发布和订阅。这种机制允许线程间通过消息传递来实现复杂的交互逻辑。

  3. 同步转异步机制 鸿蒙 OS 支持基于 Promise 的异步编程模型,包括 async 和 await 语法,以及 then 和 catch 方法。这种机制能够有效提升应用的响应性和用户体验。

并行化能力

在并行化能力方面,鸿蒙 OS 提供了两套基础实现方式。开发者可以通过 RTS(运行时系统)实现并行化,也可以通过底层库(如 C++ 标准库中的 )实现。不过,如果完全依赖底层库,可能会导致开发效率下降。为了满足业务需求,鸿蒙 OS 在年初引入了 Worker 和 TaskPool 能力。Worker 类似于传统的线程模型,每个 Worker 都有独立的内存空间和执行单元,支持通过消息进行通信。消息可以包含可序列化的数据,也可以通过指针直接迁移数据。TaskPool 则类似于线程池,能够动态管理线程数量,支持标记为 @concurrent 的函数直接在任务池中调度和运行。与安卓平台的线程池不同,鸿蒙 OS 的 TaskPool 会根据硬件条件和任务负载动态调整线程数量。这种机制避免了安卓平台中因线程池数量过多而导致的系统资源消耗问题。

接下来我们对比鸿蒙 OS 的 Worker 并行化能力和安卓端的相关特性。从多个维度来看,Worker 本质上不推荐手动创建,而是通过系统配置 build-provider.json 绑定 ETS 文件来实现创建。这一点与安卓端并无明显差异,安卓端可以通过 THREAD 等方式启动线程。

在鸿蒙 OS 5.0 以下版本(如 4.2 版本)中,主要运行的仍然是安卓系统。这种情况下,安卓线程数量存在上限,这对应用开发者来说是一个挑战。如果 SDK 集成过多,线程数可能超标,进而导致应用被系统强制终止,或出现业务场景异常崩溃等稳定性问题。

数据传输方面,鸿蒙 OS 为了优化 Worker 的性能和负载,对 Worker 的数量和单个 Worker 的传输上限进行了限制。鸿蒙 Worker 的单个传输上限类似于安卓中的 Binder 机制,也存在类似的传输限制。不过,安卓线程通常没有严格限制,因为线程本质上是一个内存拷贝过程,除非开发者通过指针等方式自定义线程间数据传输。

在传输格式上,鸿蒙 OS 支持通过 Sendable 接口进行数据传输。Sendable 是一种注解方式定义的数据结构,具有传染性,即如果一个类被标记为 Sendable,其关联属性也必须是 Sendable 类型。鸿蒙 OS 支持基础数据类型(如 number、string)和集合类型作为 Sendable 传输的内容。对于跨模块调用,鸿蒙 OS 不允许 Worker 跨 HAP 或跨 HSP 调用。相比之下,安卓应用通常运行在一个或多个 Dex 文件中,允许跨 Dex 或跨模块的线程间调用。

TaskPool 类似于双端的协程概念,是一种轻量级线程,仅存储函数。不过,TaskPool 与协程有所不同,它独立于任务维度,且任务执行时长有限制(超过 3 分钟会被系统自动回收)。安卓平台可以通过 ASM 插桩技术对线程的创建和执行进行监控和优化,但轻量级线程或协程的实现通常依赖于线程池或协程机制。

TaskPool 中的任务默认支持数据转移(transfer),不支持拷贝。此外,TaskGroup 不支持 SDK 初始化包的加载。某些同学习惯在异步线程中触发 SDK 的行为,在鸿蒙 OS 上可能会因 TaskPool 生命周期结束而导致变量被释放。







请到「今天看啥」查看全文