本文對比的是 UIWebView、WKWebView、flutter_webview_plugin(在 iOS 中使用的是 WKWebView)的載入速度,記憶體使用情況。
測試手機:iPhoneX
系統:iOS12.0
載入速度對比
測試網頁開啟的速度,只需要獲取 WebView 在開始載入網頁和網頁載入完成時的時間戳,時間戳的差即為開啟網頁的時間。
WKWebView
extension WKWebViewVC: WKNavigationDelegate {
public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
decisionHandler(.allow)
}
public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
startTime = Int(Date().timeIntervalSince1970 * 1000)
}
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
let finishTime: Int = Int(Date().timeIntervalSince1970 * 1000)
print("WKWebView \(finishTime - startTime)")
}
}
複製程式碼
UIWebView
extension WebViewVC: UIWebViewDelegate {
public func webViewDidStartLoad(_ webView: UIWebView) {
startTime = Int(Date().timeIntervalSince1970 * 1000)
}
public func webViewDidFinishLoad(_ webView: UIWebView) {
let finishTime: Int = Int(Date().timeIntervalSince1970 * 1000)
print("UIWebView \(finishTime - startTime)")
}
}
複製程式碼
flutter_webview_plugin
flutterWebViewPlugin.onStateChanged.listen((state) {
if (state.type == WebViewState.finishLoad) {
print('finishLoad:' + DateTime.now().millisecondsSinceEpoch.toString());
setState(() {
isLoad = false;
});
} else if (state.type == WebViewState.startLoad) {
print('startLoad:' + DateTime.now().millisecondsSinceEpoch.toString());
setState(() {
isLoad = true;
});
}
});
複製程式碼
為了使差異更明顯,我們選擇較為複雜的 新浪首頁 進行載入的對比,為了減小網路對載入速度的影響,我們讓手機連線同一個網路,分別進行 10 次測試然後取平均值,另外,我們需要關閉 WebView 的快取,防止快取對載入速度產生影響:
private func delegateCache() {
let cache = URLCache.shared
cache.removeAllCachedResponses()
cache.diskCapacity = 0
cache.memoryCapacity = 0
}
複製程式碼
private func deleteWebCache() {
let websiteDataTypes: Set<String> = WKWebsiteDataStore.allWebsiteDataTypes()
let dateFrom = Date.init(timeIntervalSince1970: 0)
WKWebsiteDataStore.default().removeData(ofTypes: websiteDataTypes, modifiedSince: dateFrom) {
}
}
複製程式碼
WebviewScaffold(
key: _scaffoldKey,
url: widget.url,
clearCache: true,
appCacheEnabled: false,
.
.
.
);
複製程式碼
下面使筆者進行 10 次測試所得到的資料:
UIWebView | WKWebView | flutter_webview_plugin | |
---|---|---|---|
0 | 4009 | 3384 | 3582 |
1 | 2856 | 3719 | 2869 |
2 | 2773 | 3258 | 3221 |
3 | 2776 | 3570 | 3178 |
4 | 2933 | 3386 | 3092 |
5 | 2679 | 3706 | 2956 |
6 | 2583 | 3707 | 3038 |
7 | 3145 | 2947 | 3015 |
8 | 3654 | 3038 | 3634 |
9 | 3258 | 3439 | 3132 |
avg | 3066.6 | 3415.4 | 3171.7 |
結果讓我有點驚訝,一直以為 WKWebView 會是個王者。結果看,速度上 WKWebView 略慢一點,不過總體差異不大(該結果僅僅是測試新浪的結果,僅供參考啦)。
在這裡,筆者又加了一個測試,嘗試記錄從 viewController 的 viewDidLoad 到 webview 的 didFinish 時間,測試了新浪的資料,如下:
UIWebViewA: 4970、3808、3815、4250、3556 avg(4079.8) (載入完所有頁面)
UIWebViewB: 4103、3124、3070、3256、2835 avg(3277.6)(載入sina完畢)
WKWebView: 3672、3032、2892、2912、2739 avg(3049.4)
flutter_webView: 4532、3901、4310、3496、3378 avg(3923.4)
其中可以看到,webView 有兩行,UIWebViewB 的資料就是載入 sina 主站的時間;UIWebViewA 的資料是因為在載入完 sina 主站之後,新浪又載入了一個https://r.dmp.sina.cn/cm/sinaads_ck_wap.html,所以導致總時間延長,不過即使按照 UIWebViewB 的資料來比較,也是 wkWebView 略勝一籌。
此處可以看出 flutter_webView 使用的是 wkwebView,所以它吃虧的主要原因是 flutter 包了一層。
結論: 速度(didStart -> didFinish) UIWebView > flutter_webview > WKWebView 速度(viewDidLoad -> didFinish)WKWebView > UIWebView > flutter_webview
佔用記憶體對比
這裡檢視記憶體使用的是 Xcode 的 debug session 中的 memory,首先看之前測試時,連續開啟十次新浪的記憶體情況:
接著我們在看一下開啟淘寶首頁的記憶體情況
從圖上可以看出,WKWebView 在記憶體方面有很大的優勢啊,UIWebView 的記憶體是真的傷啊,然後 debug 看了一下 flutter_webView,他使用的就是原生的 webView。
他相比較原生 WKWebView 的記憶體開銷稍大一點,從測試表現來看,一般大個 30 MB 左右。
結論:記憶體 WKWebView > flutter_webview > UIWebView
HTML5 相容性對比
可以在 html5test 中對瀏覽器的相容性進行評分,通過測試發現得分分別如下:
因為 flutter 裡使用的就是 WK,所以和原生的 WKWebView 一樣都是 444 分,比 UIWebView 的 437 略勝一籌。
結論:相容性 WKWebView = flutter_webview > UIWebView
總結
- UIWebView: 速度相比較 WKWebView 稍快一點,但是記憶體是一大硬傷,所以只要條件允許,就不推薦使用了;
- WKWebView: 速度略慢一點,不過差別不大,總體可以接受。是比UIWebView更好的選擇,推薦使用;
- flutter_webView_plugin:在iOS中使用的就是原生的WKWebView,所以總體和 native WKWebView 表現差不多。如果是混編專案中,因為它被包了一層,所以頁面載入上存在一定的劣勢,所以混編專案中仍然推薦使用 WKWebView。不過如果從多端考慮、以及專案可遷移等,那麼使用也未嘗不可,就是維護成本要增加一些,需要維護兩套 webView。這個就需要根據自己的情況自己取捨了。
再讀一篇類似文章?推薦閱讀姊妹篇:
Flutter 與 Android 原生 WebView 對比
如有任何智慧財產權、版權問題或理論錯誤,還請指正。
juejin.im/post/5c778d…
本文作者 Jay,轉載請註明原作者及以上資訊。