1. 程式人生 > >移動端本地 H5 秒開方案探索與實現

移動端本地 H5 秒開方案探索與實現

OS 前端 nat tel query variable tcl 動態加載 解析html

歡迎大家前往騰訊雲+社區,獲取更多騰訊海量技術實踐幹貨哦~

企業微信移動端項目中有需求要展示數據趨勢的可視化圖表,經過調研,最終決定以單頁面 H5 來完成,對 APP 裏的一些使用 H5 實現的功能模塊,一般體驗都比原生差,那麽怎麽提高h5加載速度?優化 h5 體驗?

適用場景:需要快速叠代、客戶端難實現的、用作展示的功能模塊,例如可視化圖表。

一、為什麽 H5 體驗糟糕

為什麽打開一個 H5 頁面會有一長段白屏時間?因為它做了很多事情,大概是:

初始化 webview -> 請求頁面 -> 下載數據 -> 解析HTML -> 請求 js/css 資源 -> dom 渲染 -> 解析 JS 執行 -> JS 請求數據 -> 解析渲染 -> 下載渲染圖片

技術分享圖片

一般頁面在 dom 渲染後才能展示,可以發現,H5 首屏渲染白屏問題的原因關鍵在於,如何優化減少從請求下載頁面到渲染之間這段時間的耗時。

二、如何優化

上述打開一個頁面的過程有很多優化點,包括前端和客戶端,常規的前端和後端的性能優化已有前輩們總結過最佳實踐,主要的是:

  • 降低請求量:合並資源,減少 HTTP 請求數,minify / gzip 壓縮,webP,lazyLoad。
  • 加快請求速度:預解析DNS,減少域名數,並行加載,CDN 分發。
  • 緩存:HTTP 協議緩存請求,離線緩存 manifest,離線數據緩存 localStorage。
  • 渲染:JS/CSS優化,加載順序,服務端渲染模板直出。

一般情況下,我們只要對照這個列表,對比差異就基本能搞定絕大部分前端性能問題了。不過我們在裏面仔細再分析下,對首屏啟動速度影響最大的就是網絡請求,包括請求 HTML、css、image 等靜態資源和展示數據的請求。

那麽將 H5 相關頁面和資源打包到客戶端中,然後客戶端將展示數據傳給頁面,通過webView加載展示,這樣幾乎不需要網絡請求,webview 只要渲染頁面,執行js即可,這樣體驗豈不是很完美?

三、具體怎麽實現?

整體思路看起來比較清晰,但是其中有幾個關鍵問題需要解決:

3.1 本地H5頁面如何和native通信:

本地 H5 頁面如何和 native 通信的方式基本有三種:jsapi、URL Scheme 和 字符串替換。具體不同方式適合使用場景有所不同:

jsapi :客戶端提供接口,註入 API讓 Javascript調用,直接執行相應Native代碼,適用於需要通過交互,進行數據請求的場景

URL Scheme : Web 端發送 URL Scheme 請求,之後 Native 攔截到請求並根據 URL Scheme 及所帶的參數進行相關操作。適用於進行頁面跳轉的場景。

字符串替換: 客戶端讀取本地 H5後,通過對 H5 中的約定的標記位進行字符串替換,然後加載展示頁面。適用於沒有復雜交互,只通過頁面渲染數據的場景。

3.2 如何開發調試和維護

開發本地 H5 模塊,很容易想到在本地通過模擬數據開發,然後將 H5 給到各客戶端打包後進行聯調。然而這樣的方案實現起來十分繁瑣,原因是 H5 資源給到客戶端打包時很分散,不統一,管理困難。

那麽我們改進一下,將使用本地 H5 實現模塊的頁面建立一個統一 git 倉庫,IOS 和 android 客戶端通過git submodule 將本地 H5 的git 外鏈到項目中,這樣客戶端中的資源就可以統一管理,解放了每次都手動繁瑣的替換打包工作。

但是這種方法其實也並不完美,H5 代替原生實現的優勢,一個在於開發成本低,另一個在於 H5 可以更加快捷的更新叠代,如果打包在客戶端中的H5 頁面就像客戶端一樣,沒法快速更新了。很容易想到將 H5 資源給到後臺,客戶端按照業務模塊預下載整個離線包,離線包根據版本做增量更新。這種的方案,就可以較好的解決上面的問題了。

技術分享圖片

四、細節優化

解決了上面的問題,本地 H5 確實可以達到秒開的加載速度,不過要達到和客戶端一樣的體驗,還需要配上一些細節優化:

預加載 webView,預拉取數據

在聯調本地 H5 頁面過程中,發現首次加載頁面時間比後續打開時間都慢很多,原因預計是 webView 首次初始化時候需要啟動資源和服務較多,於是嘗試客戶端在預先初始化 webView 方案,果然這樣第一次打開頁面時候就變快了。同時為了 H5 在第一次打開時能直接展示數據,客戶端在頁面打開前就預拉取數據並緩存,這樣來減少請求數據時間導致的白屏。

屏蔽webview HTML 內容自動識別

在 IOS webView 中默認會自動檢測 HTML 中手機號、email、地址格式並標記。 解決方法:通過添加 meta 頭來禁止默認行為

  <meta name="format-detection" content="telephone=no,email=no,adress=no">

點擊延遲

在WebView中,click通常會有大約300ms的延遲(同時包括鏈接的點擊,表單的提交,控件的交互等任何用戶點擊行為)。

解決方法:使用fastclick/touchend一般可以解決這個問題。

國際化

客戶端內的 H5 也需要國際化,前端國際化方案有很多,通常情況下都是根據項目框架選擇相應的國際化插件,然而在本地 H5 的頁面中,再引入額外插件會增加客戶端打包大小,略顯冗余。適合自己的才是最好的,這裏采用了一種適合輕量級的國際化方案。

1.提取語言文案
2.頁面和 js 中引用提取的文案
3.根據配置切換語言方案

 $(‘.i18n‘).each(function() {
     var key = $(this).attr(‘name‘);
     $(this).html(language[key]);
 });

 var language = getQueryVariable(‘en‘) ? i18n.en : i18n.zh

WKWebView 兼容

WKWebView 性能比 UIViewView 性能好很多,所以客戶端開發一般都推薦使用 WKWebView。

但是使用 WKWebView 加載本地的 HTML 時也有一些兼容問題,在 iOS8 不能在 HTML 文件中引用本地的 css 或者 js 或者圖片文件,IOS8 以上的是正常的,可以引用遠程資源。為了兼顧兼容性和秒開體驗,所以做降級方案,通過系統版本動態加載JS, IOS8 使用網絡資源,IOS8 以上使用本地資源。

還有在iOS8中,使用一些遠程的 cdn 的 css 或者 js 文件,必須註意在引用標簽上加上 charset屬性,不然 css 和 js 庫將會亂碼

五、最後

從前端優化,到客戶端緩存,到離線包,到更多的細節優化,做到上述這些點,H5 頁面在啟動上差不多可以媲美原生的體驗了。

總結起來,大體優化思路就是:減少一切網絡請求,做好預加載和緩存,盡量在用戶打開之前就加載好所有內容。這裏有些優化手段也要根據項目和實際需求來評估,需要跟開發成本和效率權衡。上述討論的僅針對功能模塊類的單頁面 H5 頁面秒開的優化方案,其他一些交互較復雜的 H5 頁面可能並不適用,還需要視實際情況和需求而定。

參考文獻

WebView性能、體驗分析與優化
70%以上業務由H5開發,手機QQ Hybrid 的架構如何優化演進?

問答
從小程序webview內嵌的h5頁面跳回小程序怎麽實現?
相關閱讀
iOS 和 H5 交互那些事 (UIWebView、WKWebView 總結篇)
H5調用底層接口的一些知識
快速開發基於 HTML5 網絡拓撲圖應用

此文已由作者授權騰訊雲+社區發布,原文鏈接:https://cloud.tencent.com/developer/article/1137813?fromSource=waitui

歡迎大家前往騰訊雲+社區或關註雲加社區微信公眾號(QcloudCommunity),第一時間獲取更多海量技術實踐幹貨哦~

移動端本地 H5 秒開方案探索與實現