前面講了前端優化和客戶端的優化。我們最后來講講細節上的優化。
細節多重優化
離線包方案在緩存上已經做得差不多了,還可以再配上一些細節優化:
公共資源包
每個包都會使用相同的 JS 框架和 CSS 全局樣式,這些資源重復在每一個離線包出現太浪費,可以做一個公共資源包提供這些全局文件。
預加載 webview
為什么打開一個 H5 頁面會有一長段白屏時間?因為它做了很多事情,大概是:
一、.首次預加載:在一個進程內首次初始化 webview 與第二次初始化不同,首次會比第二次慢很多。原因預計是 webview 首次初始化后,即使 webview 已經釋放,但一些多 webview 共用的全局服務或資源對象仍沒有釋放,第二次初始化時不需要再生成這些對象從而變快。我們可以在 APP 啟動時預先初始化一個 webview 然后釋放,這樣等用戶真正走到 H5 模塊去加載 webview時就變快了。
二、.webview 池:可以用兩個或多個 webview 重復使用,而不是每次打開 H5 都新建 webview。不過這種方式要解決頁面跳轉時清空上一個頁面,另外若一個 H5 頁面上 JS 出現內存泄漏,就影響到其他頁面,在 APP 運行期間都無法釋放了。
預加載數據
理想情況下離線包的方案第一次打開時所有 HTML/JS/CSS 都使用本地緩存,無需等待網絡請求,但頁面上的用戶數據還是需要實時拉,這里可以做個優化,在 webview 初始化的同時并行去請求數據,webview 初始化是需要一些時間的,這段時間沒有任何網絡請求,在這個時機并行請求可以節省不少時間。
具體實現上,首先可以在配置表注明某個離線包需要預加載的 URL,客戶端在 webview 初始化同時發起請求,請求由一個管理器管理,請求完成時緩存結果,然后 webview 在初始化完畢后開始請求剛才預加載的 URL,客戶端攔截到請求,轉接到剛才提到的請求管理器,若預加載已完成就直接返回內容,若未完成則等待。
三、Fallback
如果用戶訪問某個離線包模塊時,這個離線包還沒有下載,或配置表檢測到已有新版本但本地是舊版本的情況如何處理?幾種方案:
1.簡單的方案是如果本地離線包沒有或不是最新,就同步阻塞等待下載最新離線包。這種用戶打開的體驗更差了,因為離線包體積相對較大。
2.也可以是如果本地有舊包,用戶本次就直接使用舊包,如果沒有再同步阻塞等待,這種會導致更新不及時,無法確保用戶使用最新版本。
3.還可以對離線包做一個線上版本,離線包里的文件在服務端有一一對應的訪問地址,在本地沒有離線包時,直接訪問對應的線上地址,跟傳統打開一個在線頁面一樣,這種體驗相對等待下載整個離線包較好,也能保證用戶訪問到最新。
第三種 Fallback 的方式還帶來兜底的好處,在一些意外情況離線包出錯的時候可以直接訪問線上版本,功能不受影響,此外像公共資源包更新不及時導致版本沒有對應上時也可以直接訪問線上版本,是個不錯的兜底方案。
上述幾種方案策略也可以混著使用,看業務需求。
使用客戶端接口
網路和存儲接口如果使用 webkit 的 ajax 和 localStorage 會有不少限制,難以優化,可以在客戶端提供這些接口給 JS,客戶端可以在網絡請求上做像 DNS 預解析/IP直連/長連接/并行請求等更細致的優化,存儲也使用客戶端接口也能做讀寫并發/用戶隔離等針對性優化。
服務端渲染
早期 web 頁面里,JS 只是負責交互,所有內容都是直接在 HTML 里,到現代H5頁面,很多內容已經依賴 JS 邏輯去決定渲染什么,例如等待 JS 請求 JSON 數據,再拼接成 HTML 生成 DOM 渲染到頁面上,于是頁面的渲染展現就要等待這一整個過程,這里有一個耗時,減少這里的耗時也是白屏優化的范圍之內。
優化方法可以是人為減少 JS 渲染邏輯,也可以是更徹底地,回歸到原始,所有內容都由服務端返回的 HTML 決定,無需等待 JS 邏輯,稱之為服務端渲染。是否做這種優化視業務情況而定,畢竟這種會帶來開發模式變化/流量增大/服務端開銷增大這些負面影響。手Q的部分頁面就是使用服務端渲染的方式,稱為動態直出。
最后
從前端優化,到客戶端緩存,到離線包,到更多的細節優化,做到上述這些點,H5 頁面在啟動上差不多可以媲美原生的體驗了。
總結起來,大體優化思路就是:緩存/預加載/并行,緩存一切網絡請求,盡量在用戶打開之前就加載好所有內容,能并行做的事不串行做。這里有些優化手段需要做好一整套工具和流程支持,需要跟開發效率權衡,視實際需求優化。
另外上述討論的是針對功能模塊類的 H5 頁面秒開的優化方案,客戶端 APP 上除了功能模塊,其他一些像營銷活動/外部接入的 H5 頁面可能有些優化點就不適用,還需要視實際情況和需求而定。另外微信小程序就是屬于功能模塊的類別,差不多是這個套路。
這里討論了 H5 頁面首屏啟動時間的優化,上述優化過后,基本上耗時只剩 webview 本身的啟動/渲染機制問題了,這個問題跟后續的響應流暢度的問題一起屬于另一個優化范圍,就是類 RN / Weex 這樣的方案,有機會再探討。
一個H5首屏時間的優化方案大致就是前端優化、客戶端優化和細節優化了,以后還會給大家繼續分享H5技術方面的知識。