App 開發(fā):Hybrid 架構(gòu)下的 HTML5 應用加速方案
![](http://image.woshipm.com/wp-files/img/54.jpg)
在移動 App 開發(fā)領域,主流的開發(fā)模式可分為 Native、Hybrid、WebApp 三種方式。然而 2013 年,純 WebApp 開發(fā)模式的發(fā)展受到一定挫折,以 Facebook 為代表的獨立 App 轉(zhuǎn)投 Native 陣營。但是開發(fā)者對 WebApp 更新速度快,跨平臺優(yōu)勢的渴望卻并未減弱,最終的結(jié)果是促成了 Hybrid App 在 2013 年數(shù)量的激增,并且增長的速率非常之快。?簡單的說,Hybrid App是 Native App 和 Mobile Web 二者混合開發(fā)的產(chǎn)物,HTML5??的頁面被嵌入到 Natvie App 的 webview 中。因此它綜合了更新速度快,交互體驗好,跨平臺等優(yōu)點。
本文分享的就是 HTML5 頁面(尤其是被嵌入的 H5 應用)?借助 Hybrid 架構(gòu)來提升自己的加載速度和性能的一種解決方案。該方案要求你對 Hybrid App 進行以下三步驟的改造:
一:模塊化你的 H5 頁面/應用,引入模塊加載器(可選)
模塊加載器不必多說,SeaJS、requireJS、kissy loader 等耳熟能詳,任你挑選。使用模塊化的方式來開發(fā)你的應用,不僅僅將有利于后期的代碼維護,在 Hrbrid 的架構(gòu)中,還將會有利于性能的提升。
或許你有疑問:模塊開發(fā)粒度越細化,加載時請求的JS、CSS等靜態(tài)資源的數(shù)量越多,頁面的性能不會越差嗎?我的回答是:如果你僅僅是使用了模塊加載器并異步加載各個模塊,那么加載的性能一定很差,因為請求的數(shù)量太多。當然你肯定會想到在發(fā)布前打包合并靜態(tài)資源,那么對這樣的解決方案我只能給到 50 分,因為被打包合并的文件中只要有一個子文件發(fā)生變化,那么整個文件(JS或CSS)都要被重新下載,對移動帶寬而言還是個負擔。
怎么破?請繼續(xù)進行步驟二:
二:啟用 AppCache ,并引入增量更新機制
????????做過 WebApp 的同學應該會了解?mainfest?文件,Html5提供的應用緩存功能,開發(fā)者只要把需被緩存的靜態(tài)資源文件名羅列在這個列表中即可保證二次訪問時無需重新加載??雌饋聿诲e!這樣前面說的模塊化開發(fā)造成的請求數(shù)量過多的問題,至少在二次訪問時不會再發(fā)生了。嗯,這樣的方案可以給到 70 分吧。其實,Html5?提供的 mainfest 緩存機制有個比較大的問題(兼容性就先不提了):如果 mainfest 列表中的一個資源文件需要更新,那么整個 mainfest 中的其它文件也都需要被重新下載一遍。?也即是說二次訪問沒有問題了,但是 Html5 應用更新時還是會出現(xiàn)全量下載的問題。
????????別忘了,我們是 Hybrid App,還可以充分利用 Native 層的強大能力,所以拋棄mainfest吧,讓 Native 來幫助 Html5 應用緩存靜態(tài)資源文件??傮w思路是:
1、Html5 應用首次啟動時,調(diào)用 Native 提供的加載資源文件專用的 Device API 來請求所需的資源文件,由 Native 層發(fā)出真正的資源請求,并將請求結(jié)果緩存在手機的SD卡上。當然,這里完全可以優(yōu)化為一次 zip 包請求,因為 native 能夠提供強大的解壓能力。
2、H5 應用再次啟動時,所有的靜態(tài)資源都是通過 Device API 讀取本地緩存,無需再走網(wǎng)絡。
3、H5 應用出現(xiàn)靜態(tài)資源更新時,在應用啟動時首先通過 Device API 加載需要更新的文件,并更新本地緩存,其它未變更文件繼續(xù)走緩存。
????????流程看起來挺順,其中有幾個關鍵問題需要解決:
?1、如何通過 Device API 加載資源文件?
這里使用模塊加載器的優(yōu)勢就體現(xiàn)出來了,只需要在加載器中做點小修改,不直接走Http請求了,而直接調(diào)用 Native 提供的文件加載 DeviceAPI 即可。?如果你沒有模塊加載器,就需要寫統(tǒng)一的函數(shù)來做加載資源的功能了。
其實 Native 也提供了攔截機制,能夠攔截到 H5 應用發(fā)出的所有 Http 請求并進行自定義處理,可惜這樣好的功能在 Andorid 4.0 以下版本不支持。?故現(xiàn)階段還是主動調(diào)用 Device API 更靠譜。
?2、如何知道需要進行資源的更新?
????????????每次靜態(tài)資源發(fā)布都會產(chǎn)生一個唯一的發(fā)布時間戳(或是所有資源內(nèi)容的MD5編碼),H5應用啟動后,可將當前時間戳保存下來,等應用下次啟動時,請求最新的發(fā)布時間戳并與本地時間戳進行對比,若不同,則首先進行靜態(tài)資源的增量更新。
?3、如何判斷哪些是需要被增量更新替代的資源文件?
這個問題的回答會比較復雜些,核心思路是通過對前后兩次資源文件(js、css、image等)發(fā)布的內(nèi)容對比完成:
如此,H5 應用借助 Native 應用的能力完成了資源的緩存與增量更新,可以保證 H5 應用在啟動與更新時的加載速度。當然也有方案借助 HTML5 的 localstorage 來替代 Native 的緩存更新策略,但是會收到兩點限制:
1、若 Hybrid App 比較復雜,涉及多個子域甚至主域的靜態(tài)資源共享,則 localstorage 的方案在存儲空間上有上限,是5M。
2、Native?能夠支持更新包的 zip 打包下載,一次請求,并解壓覆蓋本地緩存。 localstorage 無法實現(xiàn)。
若應用可以忽略以上兩點,使用 localstorage 緩存的策略完全 ok。
三:啟用 spdy 協(xié)議
spdy?協(xié)議在移動開發(fā)上大有可為,它是HTTP協(xié)議的增強版本,能夠通過一次TCP鏈接同時請求到多個資源文件,請求速度上的提升那是自然的了,非常強大!chrome?等 webkit 內(nèi)核瀏覽器都已經(jīng)支持。?可惜若是借助瀏覽器自身使用 spdy 協(xié)議則要求靜態(tài)資源文件(js、css、image)必須是 https 的域名服務,且部署了支持 spdy 協(xié)議的后臺server。相信大多數(shù)靜態(tài)服務器都還是http 服務,是無法通過瀏覽器來直接支持的。
還是那句話,因為我們是 hybrid 應用,可以發(fā)揮native的優(yōu)勢! native 層完全可以實現(xiàn)基于 spdy 協(xié)議請求的 device API,供 H5 應用(JS)來調(diào)用。這樣就不需要 https 域名服務器也能使用 spdy了。
如果你的 Hybrid 應用已經(jīng)支持了 spdy 協(xié)議,那么你可以考慮不再需要把增量更新的資源文件打包成 zip 下載了,直接 spdy 協(xié)議并行下載即可!
SPDY 與 HTTP 協(xié)議速度對比:
總結(jié):
本文提供了一種基于 Hybrid 架構(gòu)的 H5 應用加載性能優(yōu)化方案,如有疑問及建議,歡迎探討在石破的博客中探討。
- 目前還沒評論,等你發(fā)揮!