电商RN项目秒开优化实践

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第34天,点击查看活动详情

1. 包预置、预下载 、预渲染

可以申请 App 启动时预下载首包,建议拆包后申请,可以大幅度降低包下载时间。

预渲染提前渲染页面相当于从第一个阶段创建容器便开始优化。

2. 模块拆包,Tree-shaking,懒加载

模块拆分:可以拆分首包,可大幅提升包下载更新和加载性能。

懒加载:首屏不相关模块实现懒加载,减少加载时间。

Inline Requires 采用inline require方式打包,可以把实际代码中没有使用的模块去除,减少 size。 加载模块的时机在实际真正使用到这个模块的时候,实现懒加载效果。 模块赋值时采用get属性的方式进行赋值,可以在inline require打包方式下实现懒加载。

开启 inline require 配置

// metro.config.js
module.exports = {
  transformer: {
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: true,
        inlineRequires: true,
      },
    }),
  },
};

3. 渲染引擎优化

V8 or Hermes 引擎性能对比

CodeCache:JS 预编译后的字节码产物,会缓存至磁盘,下次页面加载时可直接复用。目前 Hermes 已开启。

4. 减少 Native 通信

可减少一些 Call Native 的操作,同时将一些 ab 和静态数据增量提供批量获取的接口减少通信次数,以及减少 log 埋点的次数。

5. 预加载、引擎复用 + 深度预加载

预加载 Bundle Load:Native 提供 loadBusinessScript。 只加载 JS,不触发生命周期。

引擎复用 + 深度预加载:提前渲染备用,可自动生成 CodeCache,实际进入页面时可提升性能。

6. 前页信息复用、服务预取和缓存

前页信息复用:前页信息复用+后页骨架屏,前页跳转至后页时,可以采用前页信息提前渲染后页的部分内容。适合列表页->详情页等场景。

服务预取:框架已实现服务预取Prefetch,可以在前页提前发服务预取后页信息。适用查询页 → 列表页、列表页 → 详情页等场景。

还有一类『在途服务预取』,是在进入下个页面时提前发下个页面的主服务,可以节省 200ms 左右的页面切换时间,在途服务仅在此次进入页面时有效。

Prefetch 不要滥用,因为会引起后端服务请求量上升,针对场景适当选用。

服务预取的缓存模式也支持长期过期时间:目前唐图已采用。场景是将之前的网络请求相应报文存储到本地 cache(磁盘文件缓存和内存缓存均支持)。页面加载时直接读取缓存,如果有缓存直接渲染 UI,同时发服务获取最新数据后再 diff 刷新 UI,同时更新缓存。

由于涉及公司内部 APP 隐私就不截图了

7. BFF 接口聚合、接口设计和性能优化

BFF 接口聚合:尽可能在 BFF 层聚合首屏所需服务,需要 case by case 制定方案。

接口设计和性能优化:梳理 BFF 接口的契约合理性,以及提出具体的性能要求。

即使有接口聚合,和复用前页信息并不冲突。

对于第三方或者外部直接跳转至详情页场景, 接口聚合可以直接发挥作用;

在列表页 → 详情页场景先使用信息复用,再一次性加载好完整页面,只要控制好 CLS(至少保证页面上半部分组件位置保持不变),对用户体验仍有大量提升。

竞品 - PDD:头图复用前页图片,页面下半部分一次性服务完成渲染。

1327cc2603aa7104fd4b412328e65d4.jpg

8. 分屏渲染、页面设计约束

分屏渲染:CRN 与 Native 通信性能不佳,导致多次渲染引发“动画片”效果,Dom 量大的情况下效果更差。建议改用 Promise.all 来同步渲染性能接近的异步请求。

页面设计约束:Layout 变化会导致页面抖动,直接影响 CLS 指数(见附录参考 Web 性能核心指标之一),对用户体验影响很大。

避免导致页面 Layout 变化的设计,至少页面的上半部分 Layout 不要有大幅变化的可能性;也可以利用前页信息,自动调整当前页面的骨架屏,避免页面 Layout 大幅变化,尤其尽可能避免页面上半部分的 Layout 变化。

竞品 - 美团:复用前页信息(通常是列表页到详情页),页面上半部分不会大幅变化,即骨架屏相对固定,不会存在额外加载新元素导致页面抖动的情况。

23f131ea885c707bd6fdfaf8ebba58f.jpg

cb4a98c5c5beb36c119929ba6a19d18.jpg

9. DomTree 预渲染

DomTree 预渲染,相当于客户端实现预加载直出


以上是本人在开发公司出海App使用rn方面所总结的一些经验,项目规模不大,如有错误,欢迎各路大佬批评指教,对 DomTree 预渲染感兴趣的话,下一篇我会单独介绍一下

猜你喜欢

转载自juejin.im/post/7114691445084127246