⚡️ React Native 启动速度优化——JS 篇【全网最全,值得收藏】

本文深入探讨了React Native应用的启动速度优化,重点在JS层面,包括使用Hermes引擎加快加载速度,减小JS Bundle体积,如通过react-native-bundle-visualizer分析和优化,用day.js替代moment.js,使用babel-plugin-lodash按需引入,以及通过babel-plugin-import和babel-plugin-transform-remove-console进行进一步优化。此外,文章还提到了按需加载、分包加载和网络与渲染优化策略,以全面提升React Native应用的启动性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果你喜欢我的文章,希望点赞👍 收藏 📁 评论 💬 三连支持一下,谢谢你,这对我真的很重要!

前言

上一篇文章主要从 Native 的角度分析了 React Native 的初始化流程,并从源码出发,总结了几个 React Native 容器初始化的优化点。本文主要从 JavaScript 入手,总结了一些 JS 侧的优化要点。

1.JSEngine

rn_start_jsEngine

Hermes

Hermes 是 FaceBook 2019 年中旬开源的一款 JS 引擎,从 release 记录可以看出,这个是专为 React Native 打造的 JS 引擎,可以说从设计之初就是为 Hybrid UI 系统打造。

Hermes 支持直接加载字节码,也就是说,BabelMinifyParseCompile 这些流程全部都在开发者电脑上完成,直接下发字节码让 Hermes 运行就行,这样做可以省去 JSEngine 解析编译 JavaScript 的流程,JS 代码的加载速度将会大大加快,启动速度也会有非常大的提升。

Hermes

更多关于 Hermes 的特性,大家可以看我的旧文《移动端 JS 引擎哪家强》这篇文章,我做了更为详细的特性说明与数据对比,这里就不多说了。

2.JS Bundle

rn_start_jsBundle

前面的优化其实都是 Native 层的优化,从这里开始就进入 Web 前端最熟悉的领域了。

其实谈到 JS Bundle 的优化,来来回回就是那么几条路:

  • :缩小 Bundle 的总体积,减少 JS 加载和解析的时间
  • :动态导入(dynamic import),懒加载,按需加载,延迟执行
  • :拆分公共模块和业务模块,避免公共模块重复引入

如果有 webpack 打包优化经验的小伙伴,看到上面的优化方式,是不是脑海中已经浮现出 webpack 的一些配置项了?不过 React Native 的打包工具不是 webpack 而是 Facebook 自研的 Metro,虽然配置细节不一样,但道理是相通的,下面我就这几个点讲讲 React Native 如何优化 JS Bundle。

2.1 减小 JS Bundle 体积

Metro 打包 JS 时,会把 ESM 模块转为 CommonJS 模块,这就导致现在比较火的依赖于 ESM 的 Tree Shaking 完全不起作用,而且根据官方回复,Metro 未来也不会支持 Tree Shaking :

(Tree Shaking 太 low 了,我们做了个更酷的 Hermes)

因为这个原因,我们减小 bundle 体积主要是三个方向:

  • 对于同样的功能,优先选择体积更小的第三方库
  • 利用 babel 插件,避免全量引用
  • 制定编码规范,减少重复代码

下面我们举几个例子来解释上面的三个思路。

2.1.0 使用 react-native-bundle-visualizer 查看包体积

优化 bundle 文件前,一定要知道 bundle 里有些什么,最好的方式就是用可视化的方式把所有的依赖包列出来。web 开发中,可以借助 Webpack 的 webpack-bundle-analyzer 插件查看 bundle 的依赖大小分布,React Native 也有类似的工具,可以借助 react-native-bundle-visualizer 查看依赖关系:

Xnip2021-04-15_20-36-59

使用非常简单,按照文档安装分析就可。


2.1.1 moment.js 替换为 day.js

这是一个非常经典的例子。同样是时间格式化的第三方库, moment.js 体积 200 KB,day.js 体积只有 2KB,而且 API 与 moment.js 保持一致。如果项目里用了 moment.js,替换为 day.js 后可以立马减少 JSBundle 的体积。


2.1.2 lodah.js 配合 babel-plugin-lodash

lodash 基本上属于 Web 前端的工程标配了,但是对于大多数人来说,对于 lodash 封装的近 300 个函数,只会用常用的几个,例如 getchunk,为了这几个函数全量引用还是有些浪费的。

社区上面对这种场景,当然也有优化方案,比如说 lodash-es,以 ESM 的形式导出函数,再借助 Webpack 等工具的 Tree Sharking 优化,就可以只保留引用的文件。但是就如前面所说,React Native 的打包工具 Metro 不支持 Tree Shaking,所以对于 lodash-es 文件,其实还会全量引入,而且 lodash-es 的全量文件比 lodash 要大得多。

我做了个简单的测试,对于一个刚刚初始化的 React Native 应用,全量引入 lodash 后,包体积增大了 71.23KB,全量引入 lodash-es 后,包体积会扩大 173.85KB。

既然 lodash-es 不适合在 RN 中用,我们就只能在 lodash 上想办法了。lodash 其实还有一种用法,那就是直接引用单文件,例如想用 join 这个方法,我们可以这样引用:

// 全量
import {
    join } from 'lodash'

// 单文件引用
import join from 'lodash/join'

这样打包的时候就会只打包 lodash/join 这一个文件。

但是这样做还是太麻烦了,比如说我们要使用 lodash 的七八个方法,那我们就要分别 import 七八次,非常的繁琐。对于 lodash 这么热门的工具库,社区上肯定有高人安排好了,babel-plugin-lodash 这个 babel 插件,可以在 JS 编译时操作 AST 做如下的自动转换:

import {
    join, chunk } from 'lodash'
// ⬇️
import join from 'lodash/join'
import chunk from 'lodash/chunk'

使用方式也很简单,首先运行 yarn add babel-plugin-lodash -D 安装,然后在 babel.config.js 文件里启用插件即可:

// babel.config.js

module.exports = {
   
  plugins: ['lodash'],
  presets: ['module:metro-react-native-babel-preset'],
};

我以 join 这个方法为例,大家可以看一下各个方法增加的 JS Bundle 体积:

全量 lodash 全量 loads-es lodash/join 单文件引用 lodash + babel-plugin-lodash
71.23 KB 173.85 KB 119 Bytes 119 Bytes

从表格可见 lodash 配合 babel-plugin-lodash 是最优的开发选择。


2.1.3 babel-plugin-import 的使用

babel-plugin-lodash 只能转换 lodash 的引用问题,其实社区还有一个非常实用的 babel 插件:babel-plugin-import基本上它可以解决所有按需引用的问题

我举个简单的例子,阿里有个很好用的 ahooks 开源库,封装了很多常用的 React hooks,但问题是这个库是针对 Web 平台封装的,比如说 useTitle 这个 hook,是用来设置网页标题的,但是 React Native 平台是没有相关的 BOM API 的,所以这个 hooks 完全没有必要引入,RN 也永远用不到这个 API。

这时候我们就可以用 babel-plugin-import 实现按需引用了,假设我们只要用到 useInterval 这个 Hooks,我们现在业务代码中引入:

import {
    useInterval } from 'ahooks'

然后运行 yarn add babel-plugin-import -D 安装插件,在 babel.config.js 文件里启用插件:

// babel.config.js

module.exports = {
   
  plugins: [
    [
      'import',
      {
   
        libraryName: 'ahooks',
        camel2DashComponentName: false, // 是否需要驼峰转短线
        camel2UnderlineComponentName: false, // 是否需要驼峰转下划线
      },
    ],
  ],
  presets: ['module:metro-react-native-babel-preset'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值