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,转载请注明原做者及以上信息。

相关文章
相关标签/搜索