一 前言
React Native 是一个成熟的跨端技术方案,在 Native 端表现优异。然而,性能优化至关重要,尤其在移动端应用中,不当使用可能导致内存问题如闪退或崩溃。
本章节探讨 RN 中的性能优化,以构建高性能应用。我们将从引擎层面、渲染层面、图像层面和内存层面四个方向入手,本文重点介绍引擎与渲染层面。
二 引擎层面
React Native 由 JS 层、C++ 层和 Native 层构成,JS 层由 JSC 或 Hermes 引擎驱动。快速启动 RN 应用的关键是创建 JS 引擎。
以安卓为例,启动流程包括:创建 JS 引擎并注册通信桥,异步加载 JS Bundle,解析完毕后启动 RN 应用,构建组件树并通过 UIManager 渲染视图。JS 引擎的构建和 JS Bundle 解析运行占用较长时间,因此引擎优化至关重要。
预加载技术
引擎预加载与业务场景相关。例如,当从页面 A 进入页面 B,且下游页面 C 是 RN 页面时,可在 B 页面预加载 C 页面的引擎,构建 JS 环境,从而提高页面秒开率。
预加载的引擎不能永久保留,需在返回时回收。注意避免预加载过多页面导致内存暴涨。
引擎复用技术
引擎复用优化页面初始化加载。例如,从页面 A 进入 RN 页面 B,当 B 返回 A 时引擎被保存,再次进入 B 时直接复用,加快打开速度。
引擎复用适合短时间保活,通常几分钟。适用于列表页到详情页的场景,如商品列表到商品详情。但需注意全局变量(如 Redux 状态)的残留影响,建议在 RN 应用初始化时清除数据。
三 渲染层面
React Native 渲染成本高于 Web 端。在 Web 端,渲染流程为 element 到 fiber 到真实 DOM;在 RN 中,fiber 通过桥通知 UIManager 构建 Shadow Tree,再映射为 Native 元素渲染。RN 渲染涉及主线程、JavaScript 线程和 Shadow 线程,因此减少组件重渲染(rerender)次数至关重要。
减少 rerender 的次数
RN 中减少渲染的方案与 React 一致,包括:
-
缓存 React.element 对象:通过 React.useMemo 缓存子组件的 element,避免父组件渲染时子组件跟随渲染。
-
PureComponent:类组件继承 PureComponent,浅比较 state 和 props 以决定是否渲染。
-
shouldComponentUpdate:自定义渲染逻辑,控制组件更新条件。
-
React.memo:函数组件的缓存方案,通过 compare 函数决定是否渲染。
开发者可通过这些方式优化组件渲染性能。
渲染分片
在内存有限的低端手机上,一次性加载大量模块可能导致内存暴涨和 App 崩溃。渲染分片按优先级加载模块,重要模块优先渲染。
例如,在商品详情页,优先渲染商品信息(如图片、价格),滞后渲染推荐商品。可通过组件生命周期(如 componentDidMount 或 useEffect)控制渲染顺序,或使用高阶组件(HOC)统一管理。
长列表优化
RN 提供 FlatList 和 SectionList 组件处理长列表,支持 item 复用,提高渲染性能。
四 总结
本文从引擎与渲染两个层面介绍了 RN 性能优化手段,包括预加载、引擎复用、减少重渲染、渲染分片和长列表优化,为开发者提供实用启发。