如何實現混合 App Web 資源的打包與增量更新

Y3G發表於2016-06-19

綜述

移動 App 的執行環境具有頻寬不穩定,流量收費,啟動速度比較重要等特點,所以混合 App 如何載入 Web 資源並不是一個新問題。本文目的是總結出一種資源打包下載的思路和方案,並且提供一種打包工具。本文提到的思路只是一家之言,基本沒有參考現有方案,各位方家有不同意見歡迎留言。另外本文沒有涉及到 App 內部如何載入資源的問題,這部分我會專門撰寫一篇文章討論。

需求梳理

一般來說,Hybrid-app 對於 Web 資源下載有如下需求:

  • 頁面開啟速度要快,所以資源的下載和使用不是在同一時間進行的,有一個“預下載”的過程。

  • 資源不能重複下載,所以要有快取,但是有更新的時候必須及時更新。鑑於 WebView 的快取可控性不強,所以要有一套自定義快取機制。

  • 為了節省流量加快速度,如果資源以壓縮包為單位整體下載,那麼資源更新時要支援增量更新。同時,對於裝置端資源與最新版本相隔一個版本以上的情況,要提供全量更新。

  • 為了維持一定的健壯性,Web 資源在裝置本地和線上應各有一份部署,可以隨時切換。尤其是當裝置本地快取被刪除時,可以臨時切換到線上。

資源打包方案

為了方便開發和部署,筆者設計瞭如下打包方案:

釋出包分為四部分:

第一,是將整個 Web 資源目錄打成一個壓縮包(bundle.zip)。

第二,基於上一個版本,構建一個最新版本的增量壓縮包(update.zip)。為了簡化開發,我使用了檔案級的 diff 演算法——也就是說,對比兩個版本的程式目錄,將新增和有改動的檔案連帶目錄結構打成壓縮包。對於新版本中被刪除的檔案,本方案忽略,因為 Web 前端程式中多一個檔案並不會有任何影響。

第三,整個 Web 資源目錄以目錄的形式存在於釋出包中,目錄名為 /web,當裝置端本地資源不能用時,可以直接使用 Web 目錄中的線上資源。另外,為了方便單步除錯,除錯版 App 也使用線上資源。

第四,版本資訊檔案 update.json,本次釋出的版本號、上一個版本號,以及釋出時間存在於這個檔案中,供 App 定時下載檢查。update.json 格式如下:

{"releaseTime":"160530161454","version":9601,"lastVersion":9596}

以上就是整個釋出目錄結構,將這個目錄整體上傳到後端雲端儲存,提供下載連結,App 即可實現下載更新等功能。在暫時不用考慮 App 版本和 Web 版本配合問題的前提下,為了方便 App 開發,筆者使用了恆定不變的 URL,比如:

http://www.url_prefix.com/some_folder/webapp/app_name/update.json
http://www.url_prefix.com/some_folder/webapp/app_name/bundle.zip
http://www.url_prefix.com/some_folder/webapp/app_name/update.zip
http://www.url_prefix.com/some_folder/webapp/app_name/web/

這樣做的好處是設計 App 時約定好 URL,這些 URL 就不會變了,App 只要定時拉取 update.json 檢查版本,該更新更新即可,Web 資源釋出時只要替換掉相應的檔案即可,流程比較簡化。這樣的方案導致線上只有一個版本,所以如果你的專案中不同版本 App 需要不同版本的 Web 資源配合,那麼你就不能使用這種方式。

資源打包工具

方案確定後,我們還需要一個打包工具,方便開發人員釋出資源。顯然,這個工具不能要求開發人員自己保留老版本目錄,所以我們需要依託於版本控制工具。筆者使用 node.js 開發了一個基於 svn 的命令列打包工具 packr:

https://github.com/yusangeng/…

packr 的原理很簡單:由釋出人員確定釋出專案的 svn 地址、本次要釋出的 svn 版本號,以及上次釋出的 svn 版本號,packr 會按照上面的方案將資源打成一個釋出包。如果你用 git 的話,可以簡單改一下底層的版本控制元件。這個工具本身和前端開發無關,你可使用它為任何專案打發布包。

packr 的使用說明如下:

靜態資源打包工具(packr)使用說明

綜述

packr 是專為移動 app 混合開發設計的 web 靜態資源打包工具。

packr 通過比較兩個 svn 版本的區別(目前還不支援
git),將靜態資源專案打包為全量更新包、增量更新包,以及線上資源目錄,同時生成版本資訊 update.json。

執行環境

  • packr 基於 nodejs 實現,使用前請先安裝 nodejs。

  • packr 依賴的 npm 模組需要聯網安裝,請確保連入網際網路。

  • packr 依賴 svn 命令列工具,使用前請安裝 svn 並確保環境變數 Path 中有相關目錄。

  • packr 沒有 svn 賬戶設定入口,使用前請確保 svn 已經儲存了可用的賬戶名。

  • packr 為命令列工具,使用前請確保環境變數 Path 中有 packr 根目錄。

執行前準備

假設 packr 根目錄為 /usr/local/packr

cd /usr/local/packr npm install

命令引數

packr 命令格式如下:

packr -p=${prefix} -c=${currentVersion} -l=${lastVersion} -r=${repositoryURL}

其中:

  • prefix 為輸出目錄,如果不設定,則輸出於當前目錄。

  • currentVersion 為當前釋出版本的 svn 版本號。

  • lastVersion 為上一個版本的 svn 版本號。

  • repositoryURL 為 svn 版本庫地址。

輸出

packr 輸出為一個 zip 壓縮包,其中有如下檔案或目錄:

  • bundle.zip 新發布版本的全量更新包。

  • patch.zip 增量更新包,其中有新增和改動過的檔案。

  • web 線上資源目錄,供客戶端或瀏覽器在不使用快取時直接訪問。

  • update.json 版本資訊檔案,其中以 json 格式記錄了新版本和上一個版本的版本號。

相關文章