【背景】
目前,我们的app中采用Native+RN的混合模式开发,每个由RN开发的页面,页面的加载都是加载的一个Bundle文件,而一个Bundle文件的大小为500-600Kb。
在没有内置bundle文件的情况下,用户想要使用所有由RN开发的功能,需要下载 n* 500 kb的文件。
在有内置bundle文件的情况下,如果一个页面有更新,那么用户至少需要下载500kb的文件。
在移动端,频繁的需要去下载500kb大小的文件,是无法被接受的。
【目的】
1、控制bundle资源包的大小,为内置安装包瘦身
2、减小页面更新bundle文件大小,减少App端下载bundle的流量
【详细设计】
1)google-diff-match-patch简介:
要对文本文件的进行比较的时候,可以考虑使用google-diff-match-patch,它可以对文本文件进行比较、匹配和生成补丁的操作。
他的官网是:http://code.google.com/p/google-diff-match-patch/
使用google diff的话,这个差异就是从左边的字符串变成右边的字符串所需要的最少的步骤,每个步骤只能做“保持不变”、“插入”或者“删除”操作。
使用入门可以参考:http://blog.csdn.net/codetomylaw/article/details/52872065
2)bundle文件拆分方案:
commonPart.bundle生成的方法如下:(android 和 iOS的commonPart 需要分开生成)
curl 'http://localhost:8081/blank.ios.bundle?minify=true&dev=false' -o common.ios.bundle
其中blank.ios.js 文件内容如下:
import React, { Component } from 'react';
import {} from 'react-native';
拆分完成后的bundle示意图如下:
3)bundle文件diff和patch流程
【资源打包】
提供一个shell,可以支持bundle文件的diff,生成patch文件,并对其zip压缩。
使用效果如下:
【效果】
可以看到,bundle文件由560kb 缩小到了15kb。
综合以上,就达到了bundle文件瘦身的目的。
以下更新于20170328
【合并差异diff文件生成bundle,导致Android白屏问题】
【现象】
安卓端2.0.1版本升级安装到2.1.0后,app启动,长时间白屏,导致ANR。选择等待,重新进入app,白屏消失,恢复正常。
【分析】
1、从bugly后台可以看到导致ANR的堆栈,从堆栈可以看出,错误出现在:
Object[] results = diff_match_patch.patch_apply(patches, commonStr);
此段代码的作用是:google-diff-match-patch 合并差异描述文件,生成业务完整bundle文件。
2、耗时分析
在app启动的时候,会在主线程中初始化RNSDK,执行initRnManager方法,初次使用时会unZip bundle描述文件, 执行 diffExecute 方法, 生成业务完整bundle,当业务bundle都生成完毕后,会进入app首页。
分析 diffExecute 方法执行时间,发现在不同的Android机型下,合并一个bundle文件耗时时间在 100 - 3500 ms不等。目前共4个bundle文件,最长耗时达到13000 ms,因此导致启动app时ANR。
在Android平台下,出现这种耗时差异,主要是由于Android设备性能差异较大,对大文件的diff操作有不同的响应时间。
在iOS平台下,由于iOS系统性能好,不存在此问题。
【解决方案】
将内置差异描述文件改为内置完整bundle文件
用户初次使用app时,只需要将asset里内置的业务bundle 拷贝到 data/data/com.xxx.xxx/app_bundle/时间戳/ 目录,去掉match-patch 流程。这样app启动时可以直接使用内置的完整bundle文件。
备注:
1、对内置文件的处理只发生在用户初次使用app、版本覆盖安装、用户通过系统或第三方工具手动清除app对应的资源文件。
2、增量更新功能,还是使用差异描述文件的方式下发,但是执行是在一个BundleTask 异步任务中,在后台执行,不影响主线程。