在iOS中,app內(nèi)嵌網(wǎng)頁無非兩種方式,一是使用UIWebView(ios 2.0),二是使用WKWebView(ios 8.0);WKWebView修復(fù)了很多UIWebView的不足,比如性能、內(nèi)存等等。
打開一個(gè)webview經(jīng)歷的幾個(gè)階段:
- 交互無反饋
- 到達(dá)新的頁面,頁面白屏
- 頁面基本框架出現(xiàn),但是沒有數(shù)據(jù),頁面出于loading狀態(tài)
-
出現(xiàn)所需的數(shù)據(jù)
如果從程序上觀察,WebView啟動(dòng)過程大概分為以下幾個(gè)階段:
time.png
webview的初始化
與瀏覽器不同,app中打開webview的第一步并不是建立連接,而是啟動(dòng)瀏覽器內(nèi)核。
- 在瀏覽器中,我們輸入地址時(shí),瀏覽器就可以開始加載頁面了;
- 而在客戶端中,客戶端需要先花費(fèi)時(shí)間初始化WebView完成后,才開始加載。所謂的加載即網(wǎng)絡(luò)請求;
一般來說HTML在開始接收到返回?cái)?shù)據(jù)的時(shí)候就開始解析HTML并構(gòu)建DOM樹,如果沒有JS阻塞的話,一般會(huì)相繼完成。
WKWebView的內(nèi)存占用優(yōu)勢比較大,但是初始化比較慢;
UIWebView和android的webView在首次初始化時(shí)都要消耗大量內(nèi)存,之后每次新建 WebView會(huì)額外增加一些內(nèi)存。
在webView中,click事件通常會(huì)有大約300ms的延遲。
使用過大圖片(2M)可能會(huì)導(dǎo)致webView crash。
webView被運(yùn)營商劫持、注入問題
由于webView加載的頁面代碼是從服務(wù)器動(dòng)態(tài)獲取的,這些代碼將會(huì)很容易被中間環(huán)節(jié)所竊取或者修改,其中最主要的問題出自地方運(yùn)行商和一些WiFi。
主要問題包括:
- 無視通信規(guī)則強(qiáng)制緩存頁面。
- header被篡改。
- 頁面被注入廣告。
- 頁面被重定向。
- 頁面被重定向并重新iframe到新頁面,框架嵌入廣告。
- HTTPS請求被攔截。
- DNS劫持。
針對頁面注入,解決方案:
1、使用CSP(Content Security Policy)
CSP可以有效的攔截頁面中的非白名單資源,而且兼容性較好。在美團(tuán)移動(dòng)版的使用中,能夠阻止大部分的頁面內(nèi)容注入。
2、HTTPS
HTTPS可以防止頁面被劫持或者注入,然而其副作用也是明顯的,網(wǎng)絡(luò)傳輸?shù)男阅芎统晒β识紩?huì)下降,而且HTTPS的頁面會(huì)要求頁面內(nèi)所有引用的資源也是HTTPS的,對于大型網(wǎng)站其遷移成本并不算低。
HTTPS的一個(gè)問題在于:一旦底層想要篡改或者劫持,會(huì)導(dǎo)致整個(gè)鏈接失效,頁面無法展示。這會(huì)帶來一個(gè)問題:本來頁面只是會(huì)被注入廣告,而且廣告會(huì)被CSP攔截,而采用了HTTPS后,整個(gè)網(wǎng)頁由于受到劫持完全無法展示。
對于安全要求不高的靜態(tài)頁面,就需要權(quán)衡HTTPS帶來的利與弊了。
客戶端內(nèi)部打開第三方webView
一般來說,客戶端內(nèi)的WebView都是可以通過客戶端的某個(gè)schema打開的,而要打開頁面的URL很多都不是寫死在客戶端內(nèi)部的,而是可以由url中的參數(shù)傳遞過去的。
那么一旦url可以通過外界自定義,那么就有可能在客戶端內(nèi)部打開一個(gè)外部的網(wǎng)頁。比如通過掃碼等方式。
解決方案:在內(nèi)嵌的webview中應(yīng)該限制允許打開的webview的域名,并設(shè)置運(yùn)行訪問的白名單?;蛘弋?dāng)用戶打開外部鏈接錢給用戶強(qiáng)烈而明顯的提示。
現(xiàn)狀與發(fā)展
在一個(gè)客戶端內(nèi),native目前主要提供高效而基礎(chǔ)的功能;內(nèi)部的webview則添加一些性能體驗(yàn)要求不高但動(dòng)態(tài)化要求高的能力。
提高客戶端的動(dòng)態(tài)性,或者提高webview的性能,都是提升app功能覆蓋的方式;目前市面上的各種框架都是對這個(gè)趨勢的嘗試。
隨著技術(shù)的發(fā)展,webview的性能、體驗(yàn)、和安全問題也將逐漸的改善,在App中所占的比重也必將會(huì)越來越大。

