一、什么是拆包?
RN打包的目标产物是一个jsbundle,包含RN基础库、第三方库、业务组件等,随着业务的迭代,模块的增加,这个包往往很大。如果Native调用一个RN业务模块,把整个导入,一个是加载慢、耗内存。这就诞生拆包技术,顾名思义就是将大包拆分小的包,按需加载。
一般做法都是重构RN工程,抽离通用代码、第三方库、RN源码等打包为基础包,然后各个业务在基础包的基础上进行开发。
这样做的好处是可以降低对内存的占用,减少加载时间,减少热更新时流量带宽等,在优化方面起到了非常大的作用。
通过打开.bundle或者.jsbundle文件,发现其实就是压缩过的js代码,可以用读文件的方式读取,然后交给底层的js引擎执行解析。
二、基础原理概述
1、拆包关键bridge
RCTBridge 是对 JavaScriptCore 中 Bridge 的封装,每个 bridge 都是一个独立的js环境。
1.1、RN 的启动流程可以简单概括为:
- Native 编译并启动
- 创建 js 虚拟机环境。
- 创建 bridge。
- 通过 bridge 获取js线程来解析 js 代码(可以是远程包和离线包)。
- 运行 js 代码,并根据参数创建 RootView。
由上可见, bridge 在 RN 中起到承上启下的作用,在做 RN 拆包的时候是重点考虑的对象。
1.2、单包?多包?
目前RN拆包针对 brdige 有两种主流方案,分别是单 bridge 和多 bridge。
-
多个bridge最大问题是耗内存。
因为每个 bridge 都得先加载 common 包,再加载具体业务包,这样会很浪费内存。 -
多个bridge最大好处动态加载更方便。
不重启 APP 的情况下更新 bundle很方便,只需要重新指定路径加载或者执行 reload -
单个bridge好处是占用内存少,且不用管理 bridge 的缓存和复用问题。
-
单个bridge最大缺点,动态更新需要多很多配置,易出错
三、拆包工具的选择
- metro 拆包:业界主流方案。
- moles-packer:携程团队自研方案。
- diff patch 拆包:
四、拆包后遇到的问题
- 1、按序加载基础包和业务包
开始启动App的时候,预加载base部分;然后开始进行热更新逻辑;最好进入具体RN业务线的时候,开始加载业务线自己对应的bundle。
问题:bundle 加载完成回调?
需要严格按照通用的bundle ---> 业务bundle 顺序加载,因此必须获取通用bundle加载完成的回调事件。
问题:需要扩展支持RCTBridge多次加载bundle的能力?
iOS端,需要暴露RCTBridge的内部- (void)executeSourceCode:(NSData *)sourceCode sync:(BOOL)sync;
-
2、热更新改造
-
3、混合开发的路由方案
混合开发后,路由表的方案设计,复杂的应用往往都是采用混合路由的方式,即有纯RN的路由、也需要Native的路由。 -
4、路由表的调整
拆包之后路由表怎么维护呢?由于拆分成了多个 bundle,路由表散落在了多个bundle 中,不同 bundle 之间如何跳转。如果路由名产生了冲突,就会导致跳转异常和错乱,所以这里就需要给每个路由加上一个所属 bundle 标识。 -
5、多 bundle 的 debug。
网友评论