Flutter 與 iOS 原生 WebView 對比

本文對比的是 UIWebView、WKWebView、flutter_webview_plugin(在 iOS 中使用的是 WKWebView)的加載速度,內存使用狀況。html

測試手機:iPhoneX
系統:iOS12.0html5

加載速度對比

測試網頁打開的速度,只須要獲取 WebView 在開始加載網頁和網頁加載完成時的時間戳,時間戳的差即爲打開網頁的時間。git

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 的緩存,防止緩存對加載速度產生影響:github

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 次測試所獲得的數據:web

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 略慢一點,不過整體差別不大(該結果僅僅是測試新浪的結果,僅供參考啦)。swift

在這裏,筆者又加了一個測試,嘗試記錄從 viewController 的 viewDidLoad 到 webview 的 didFinish 時間,測試了新浪的數據,以下:api

UIWebViewA: 4970、380八、381五、4250、3556 avg(4079.8) (加載完全部頁面)
UIWebViewB: 410三、312四、3070、325六、2835 avg(3277.6)(加載sina完畢)
WKWebView: 367二、303二、289二、29十二、2739 avg(3049.4)
flutter_webView: 453二、390一、43十、349六、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,首先看以前測試時,連續打開十次新浪的內存狀況:

UIWebView.png

WKWebView.png

flutter_webView.png

接着咱們在看一下打開淘寶首頁的內存狀況

UIWebView.png
WKWebView.png
flutter_webView.png

從圖上能夠看出,WKWebView 在內存方面有很大的優點啊,UIWebView 的內存是真的傷啊,而後 debug 看了一下 flutter_webView,他使用的就是原生的 webView。

他相比較原生 WKWebView 的內存開銷稍大一點,從測試表現來看,通常大個 30 MB 左右。

結論:內存 WKWebView > flutter_webview > UIWebView

HTML5 兼容性對比

能夠在 html5test 中對瀏覽器的兼容性進行評分,經過測試發現得分分別以下:

UIWebView.png
WKWebView.png
flutter_webView.png

由於 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,轉載請註明原做者及以上信息。

相關文章
相關標籤/搜索