React Native拆包优化:助力如祺App提升热更新效率

背景&思考

React Native(以下简称RN)应用的代码结构涵盖了RN源码、第三方依赖库以及业务逻辑代码。在实际开发中,我们常常面临的问题是那些相对固定且不经常变动的依赖与频繁更新的业务逻辑代码混杂在一起。为了优化应用性能,降低用户在更新版本时的流量消耗,我们采用"拆包增量更新"的策略,将不经常改变的依赖与业务逻辑代码分离,从而通过"增量热更新"来压缩热更包的大小,确保在应用更新时能够达到最优效果。

传统的应用打包方法通常将所有代码整体打包成一个Bundle.js文件(假设包体积为10MB)。然而,通过拆包并引入"增量热更新"的概念,我们可以将这个庞大的包拆分为一个相对稳定的依赖包(2MB)和多个业务包(每个包大小2MB)。当某个业务包需要进行热修复时,只需下发该业务包的增量更新,而不是整个包,从而实现精准的热更新。通过这种方式,APP热更新所需的流量仅为该业务包的增量,而不是整体10MB,这在效率上有了明显的提升。

因此,拆包的核心目标是通过"增量热更新"提高RN热更新的效率,同时显著降低用户在更新应用版本时所需的流量。这一优化手段旨在使应用的维护更加灵活,提供更高效的用户体验,并为RN开发者带来更智能、精准的应用更新管理方式。

技术实现

01 拆包架构设计

我们根据业务区分之后将RN代码拆分为9个子包,分别对应9个打包子入口文件,包括:

common:包主要用于存放rn源码和第三方依赖库

basic:包主要用于存放公共函数,组件,调用原生方法的一些工具包

resource:包用于存放所有图片,文件等静态资源

其余6个业务子包:车主,顺风车乘客,专车乘客,首页,设置,营销等。

以此来达到进行多包构建和分包的目的。

02 如何打包构建

上述我们已经将RN代码根据业务进行划分之后,形成了多包构建的新模式,那么如何做到构建之后在下发过程中进行增量热更新呢?这里我们对构建脚本进行了优化,提出了2种新的打包策略:手动升级自动升级主要是针对于子包版本号的生成规则进行定义。

这里得先提出我们打包的目录结构设计:

info.json文件的结构:

由于拆包之后子包间是存在着版本依赖关系的,所以我们对子包的描述文件增加了以下几个字段用于描述记录相关依赖包的版本信息:

minAppVersion,maxAppVersion,commonMinVersion,commonMaxVersion,basicMinVersion,basicMaxVersion。common包依赖于app主包,basic包依赖于common包,其余业务子包依赖于common和basic包,一旦依赖包发生版本更新,相应的子包也必须版本更新才能保持代码同步。

手动升级:

主要用于app常规需求迭代,RN子包跟随app一起升级,需要指定一个大版本号bigVersion(一般为app版本号),此时子包的版本号,依赖版本号都跟随着这个大版本号,例如bigVersion=100026300,则子包的bundleVersionCode,minAppVersion,maxAppVersion,commonMinVersion,commonMaxVersion,basicMinVersion,basicMaxVersion都等于100026300。

自动升级:

主要用于RN热更,app版本号不变,此时默认是取中台仓库中最新版本的RN子包与当前打包之后的bundle包进行对比,若md5值不相等,则说明该子包存在代码更新,则版本号在最新版本子包的版本号基础上 +1

比如:当前中台仓库中的basic包版本号是100026300,本次打包之后的basic包与仓库中最新的对比,如果md5值不相等,则说明basic包存在代码更新,则本次打包的basic包的bundleVersionCode为100026301

关于上述MD5值如何生成:

对于上述手动升级而言,子包的版本号升级比较简单,直接跟随主包,但是对于自动升级,由于涉及到md5值的对比,所以这里我们必须针对md5值的生成进行设计。

1.普通业务子包打包之后都会有一个index.bundle文件,我们可以直接对这个文件进行md5值的生成,以此来区分是否发生代码更新;

2.resource这个资源包比较特殊,由于其index.bundle文件是不存在业务代码的,所以不能简单直接对其进行md5值的计算,为此,我们提出了"递归遍历资源包的每个文件生成md5+资源文件路径 "来生成一个资源包的唯一md5值,详情见下图:

03 如何增量上传

上述针对拆包之后进行多包构建,在本地构建或者是Jenkins平台打包之后依然是一个完整的压缩包,只不过这个压缩包包含着9个子包文件夹,这样子方便于我们开发进行本地代码调试,但是日常开发中往往发生代码变动只涉及到少量的1-2个业务包,所以我们必须按需进行上传至中台,没必要上传完整的热更包,以此减轻服务器资源的压力。根据上述的打包目录结构设计,每个子包都有一个info.json文件记录着当前子包的相关版本信息,所以当热更包上传中台的同时,服务端接口要进行版本号的判断,如果当前子包的版本号与中台仓库的最新版本号不一致,说明代码发生更新,至上传至cos桶,否则废弃。

04 如何增量下发

客户端每次启动的同时会调用服务端的一个检查版本更新接口,上传每个子包的相关版本参数,以此来判断哪些子包需要进行版本更新,比如某次版本更新涉及到"首页"和"设置"两个子包,则服务端需要根据两个子包的下载地址从cos桶下载下来放到系统临时目录,然后再统一压缩成一个热更包,重新上传至cos桶,然后把这个新的热更包地址返回给客户端,客户端拿到这个地址之后下载到本地完成热更新。以下是相关判断逻辑举例:

总结与展望

亮点

1.降低服务器资源使用率:

拆包使得每次构建完成的RN热更包是增量上传的方式,大大减少了服务器存储空间的使用率

2.提高热更新效率:

采用"增量热更新"概念实现了对业务包的精准热修复。相比传统的整体热更新方式,这种方法更加高效,因为只有发生变动的业务包才会被更新,而其他部分保持不变。这一精准度不仅提升了热更新的速度,同时也节省了用户设备上的存储空间

3.降低用户更新版本的流量消耗:

在弱网环境下,用户更新版本的速度更快了,使得用户体验更加顺畅,愉快,app使用起来更加丝滑。

展望

本次"拆包增量热更新"的方案已落地于如祺出行APP乘客端,未来将更广泛应用于其它混编的应用程序,比如司机端的改造。另外,拆包增量的思想也可以运用于小程序,H5等其他web端的应用程序,使更新更加高效快捷。

相关推荐
NoloveisGod11 分钟前
Vue的基础使用
前端·javascript·vue.js
GISer_Jing13 分钟前
前端系统设计面试题(二)Javascript\Vue
前端·javascript·vue.js
海上彼尚42 分钟前
实现3D热力图
前端·javascript·3d
杨过姑父42 分钟前
org.springframework.context.support.ApplicationListenerDetector 详细介绍
java·前端·spring
理想不理想v1 小时前
使用JS实现文件流转换excel?
java·前端·javascript·css·vue.js·spring·面试
惜.己1 小时前
Jmeter中的配置原件(四)
java·前端·功能测试·jmeter·1024程序员节
EasyNTS1 小时前
无插件H5播放器EasyPlayer.js网页web无插件播放器vue和react详细介绍
前端·javascript·vue.js
poloma1 小时前
五千字长文搞清楚 Blob File ArrayBuffer TypedArray 到底是什么
前端·javascript·ecmascript 6
guokanglun2 小时前
Vue.js动态组件使用
前端·javascript·vue.js
Go4doom2 小时前
vue-cli3+qiankun迁移至rsbuild
前端