今天 去啊 App 5.1.1 已經釋出了,航旅 Hybrid 混合架構有了更進一步的落地,這輪優化目标是搞定H5真正的“無縫秒出”。
先來看效果,去啊App 2G 網絡下購買國際機票,30秒完成,除了搜尋入口頁,清單往下到付款頁的前端都是H5 Page,大家感受一下:
目測性能是可觀的。盡管H5包的離線化隔絕了弱網對秒出的幹擾,裝置本地 IO 耗時也是不能忽視的,算上zip的解壓縮,僅在裝置本地 IO 完全一個 HTML(包含其攜帶的資源檔案)也會達到秒級的耗時,在iphone5上也會有0.5秒左右的白屏時間。
另外,HTML 本身的優化依然無法繞過,WebView 裡 JS 的運作效率通常是 Mobile Browser 裡的四分之一。是以 JS 必須盡可能靠後的介入渲染,CSS 必須盡可能靠前的介入渲染。而在當下前端開發習慣來看,頁面通常會至少阻塞加載一個種子檔案(比如kissy),而在Mobile裝置中,哪怕是無幹擾Dom的JS阻塞運作都會帶來0.3秒左右的白屏延時。
是以,H5容器的IO優化和HTML渲染提前是本期改造的重點,即:
H5 容器加載資源的 IO 優化:幹掉zip包的即時解壓,離線包更新後立即解壓散列到SD卡,每次建立 View 時直接從裝置讀檔案,本地檔案管理依然基于标準的H5包規範。
HTML 本身的頁面優化,CSS 提前,JS 置後。
其實無非是将同步的腳本改成異步。先保證帶樣式的頁面架構秒出來,然後去執行 JS。從性能資料上甚至看不出差别,但從感官上的提升非常明顯,我甯願讓你先看到界面,而不是白屏。
這樣設計主要是為了做線上線下的開關切換,緊急問題可随時配置到線上頁面,線上頁面是可以随時部署的,離線頁面則涉及到推包。為了做這層開關,就會帶來判斷檔案是線上還是離線的問題。
因為H5容器虛拟域的代理層會引導 WebView 去本地而不是網絡讀檔案。如果讀不到本地檔案,再建立一個HTTP請求去對應的線上請求檔案。如果通過 IO 一次再判斷本地是否存在檔案,顯然實際的 IO 次數依然降不下來(所有的資源檔案請求都必須要 IO 一次手機硬碟),為了降低實際 IO 次數,我們針對每個 H5 離線包生成一個本地資源檔案清單(cache_info.json),并同時将域名路徑和檔案路徑做成了映射 Map,這個映射表讀入記憶體後備用,涉及到H5的通路,用這個 Map 過濾下就能直接找到要讀的檔案位置,Map 比對不上就直接建立HTTP從網上取檔案了,這樣可以避免無必要的 IO。
AngularJS 在移動端的加速
去啊 Hybrid 中存在大量的清單頁,比如上面的團購和視訊中國際機票的例子,AngularJS 是最适用于這種場景。但 AngularJS 目前沒有專門針對 Mobile 做優化,而在 Mobile 裝置裡,<code>hashchange</code>帶動資料模型<code>data-model</code>的變更,進而通過<code>View</code>來渲染。首次渲染稍慢,因為要等<code>Model</code>準備好才出視圖,無論如何界面也秒不出來(從<code>hashchange</code>到出界面至少0.8 秒)資料結構在稍微複雜點,立即破1秒,當然這個時間是伴随着首次加載建構DOM的幹擾。
幾點改造:
AngularJS 種子檔案異步載入
非資料關聯的HTML一律預裝在頁面
首次加載幹掉任何影響頁面抖動的 HashChange
基礎資料的離線化(比如城市清單)
這幾點無非是讓首次渲染能盡快的展現,接下來 OPOA 中的程式設計就是 AngularJS 所擅長的了。
那麼問題來了,離線包裡怎麼做?
建構為:
這樣,在離線包裡的 TMS 内容就和 H5 頁面完全分開了,畢竟 TMS 由于變更頻繁,是沒辦法直接做離線化的。但上面這段腳本顯然會阻塞頁面渲染,是以<code>offline-tms-parser</code>提供了異步的版本,即将:
然後在 H5 頁面頂部塞一個<code>get_tms_fragment</code>的實作即可。
如此,基于 AWP 平台開發業務将不受任何影響,工具幫我們處理好 TMS 和 H5 頁面的百分百解耦,離線包裡也可以大量使用 TMS 了。
盡管如此,也必須不能濫用 TMS,代碼邏輯層面的 View 和 Data 的解耦仍然是必須要做的。
grunt-kmc 的速度:
grunt-kmb 的速度:
整整一倍的提速,太讓人垂涎期待了。
本期的優化沒有多少高科技的東西,大都是體力活,将技術做透。好的體驗真的是靠點滴的積累,需要花時間去磨。
我在這次集團前端技術峰會上的彙報裡,提到過我們面臨的挑戰:
去啊 App 是介于工具化的錢包App和營運化的手淘App之間,既有營銷活動,也有工具化、流程化的 PageFlow。将标準化的 PageFlow 的性能做到極緻,接下來的挑戰就是如何将營運活動也做到智能的推送,完成這類頁面的離線部署。
當然,活動頁面的離線化部署目前來看不是我們面臨最急迫的難題,最棘手的是資料打通的問題:
看這個場景,在錢包App做了一個引流的入口,喚起了去啊App,并定位到機票搜尋結果頁:
目前我們很難跟蹤喚起的效果,手機裡的App是資訊孤島,很難通過簡單的傳參來把跨 App 的 PageFlow 串聯起來。即使參數能帶過來,但身份資訊、登陸狀态和賬号關聯能否也能帶過來呢,每一項都是很有挑戰。
我在前兩天給航旅的新人教育訓練上,分享了我了解的《Mobile First》,這段話是值得分享給大家一起共勉的:
内聚的 App 和散列的 Web 似乎是一個不可調和的沖突。企業傾向于認為隻有提供越來越多地功能,才能滿足使用者不斷膨脹的需求,但又會打破原有應用的簡便易用。當兩者無法調和,資訊膨脹到必須散列到不同的端時,通過 Web 技術将這些資訊孤島關聯起來就顯得至關重要。
是以,我們之前所做的所有技術的優化,都是在為建構無線“前端/終端”技術體系夯實根基,是以這一輪無線All In 從某種意義上看是一種原始積累,第二輪無線All In才會迎來真正的非标商品的個性化、多元化時代。這時我們的技術體系将着重解決這幾類問題:
千人千面,重點解決面向不同人群做手機裡的定制化功能的問題
無線大資料,重點解決打破App間的資訊孤島,讓跨端的資料化營運更加高效、可靠
無線開源,讓 B 商家參與進來,像手淘一個(Native)商品詳情頁通吃所有商品的時代很快就會被更個性、多彩的非标商品打破,這時,大量垂直領域的産品模式設計更多要靠商家參與,而不是我們自己那幾個産品經理,是以,更開源、更自由的手機店鋪,閉環服務才是王道。
說到閉環,去啊的機票購買流程,是無線端閉環的經典案例:
這個例子是從錢包的入口開始購機票流程,通過短信、Push、下載下傳、喚起等操作,将使用者搗騰到去啊App裡(整個過程體驗流暢,估計你也很難厘清楚哪些Page是H5的、哪些是Native的吧)。
So,開源 + 閉環,是我理想中的無線 Hybrid 技術的終極狀态,去啊 Hybrid 技術積累也才剛剛開始。