ReactNative中实现动态导入的示例代码.docxVIP

ReactNative中实现动态导入的示例代码.docx

  1. 1、本文档共12页,可阅读全部内容。
  2. 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多

ReactNative中实现动态导入的示例代码

目录背景多业务包动态导入Metro打包原理打包过程bundle分析__d函数__r函数方案设计分识别入口树拆分bundle生成合总结

背景

随着业务的发展,每一个ReactNative应用的代码数量都在不断增加,bundle体积不断膨胀,对应用性能的负面影响愈发明显。虽然我们可以通过ReactNative官方工具Metro进行拆包处理,拆分为一个基础包和一个业务包进行一定程度上的优化,但对日益增长的业务代码也无能为力,我们迫切地需要一套方案来减小我们ReactNative应用的体积。

多业务包

第一个想到的就是拆分多业务包,既然拆分为一个业务包不够,那我多拆为几个业务包不就可以了。当一个ReactNative应用拆分为多个业务包之后其实就相当于拆分为多个应用了,只不过代码在同一仓库里。这虽然可以解决单个应用不断膨胀的问题,但是有不少局限性。接下来一一分析:

链接替换,不同的应用需要不同的地址,替换成本较高。页面之间通信,之前是个单页应用,不同页面之间可以直接通信;拆分之后是不同应用相互通信需要借助客户端桥接实现。性能损耗,打开每个拆分的业务包都需要单独起一个ReactNative容器,容器初始化、维持都需要消耗内存、占用CPU。粒度不够,最小的维度也是页面,无法继续对页面中的组件进行拆分。重复打包,部分在不同页面之间共享的工具库,每个业务包都会包含。打包效率,每一个业务包的打包过程,都要经过一遍完整的Metro打包过程,拆分多个业务包打包时间成倍增加。

动态导入

作为一个前端想到的另一方案自然就是动态导入(Dynamicimport)了,基于其动态特性对于多业务包的众多缺点,此方案都可避免。此外拥有了动态导入我们就可以实现页面按需加载,组件懒加载等等能力。但是Metro官方并不支持动态导入,因此需要对Metro进行深度定制,这也是本文即将介绍的在ReactNative中实现动态导入。

Metro打包原理

在介绍具体方案之前我们先看下Metro的打包机制及其构建产物。

打包过程

如下图所示Metro打包会经过三个阶段,分别是Resolution、Transformation、Serialization。

image

Resolution的作用是从入口开始构建依赖图;Transformation是和Resolution阶段同时执行的,其目的是将所有module(一个模块就是一个module)转换为目标平台可识别语言,这里面既有高级JavaCript语法的转换(依赖BaBel),也有对特定平台,比如安卓的特殊polyfills。这两个阶段主要是生产中间产物IR为最后一阶段所消费。

Serialization则是将所有module组合起来生成bundle,这里需要特别注意MetroAPI文档中SerializerOptions中的两个配置:

签名为createModuleIdFactory,type为()=(path:string)=number。这个函数为每个module生成一个唯一的moduleId,默认情况下是自增的数字。所有的依赖关系都依仗此moduleId。签名为processModuleFilter,type为(module:Array)=boolean。这个函数用来过滤模块,决定是否打入bundle。

bundle分析

一个ReactNative典型的bundle从上到下可以分为三个部分:

第一部分为polyfills,主要是一些全局变量如DEV;以及通过IIFE声明的一些重要全局函数,如:__d、__r等;第二部分是各个module的定义,以__d开头,业务代码全部在这一块;第三部分是应用的初始化__r(react-native/Libraries/Core/InitializeCore.jsmoduleId)和__r(${入口moduleId})。

我们看下具体函数的分析

__d函数

functiondefine(factory,moduleId,dependencyMap){

constmod={

dependencyMap,

factory,

hasError:false,

importedAll:EMPTY,

importedDefault:EMPTY,

isInitialized

您可能关注的文档

文档评论(0)

132****1508 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档