1. 程式人生 > >《React-Native系列》40、 ReactNative之bundle檔案瘦身

《React-Native系列》40、 ReactNative之bundle檔案瘦身

【背景】

目前,我們的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,它可以對文字檔案進行比較、匹配和生成補丁的操作。


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

【現象】

安卓端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 非同步任務中,在後臺執行,不影響主執行緒。