本文对比的是 UIWebView、WKWebView、flutter_webview_plugin(在 iOS 中使用的是 WKWebView)的加载速度,内存使用情况。
测试手机:iPhoneX
系统:iOS12.0
加载速度对比
测试网页打开的速度,只需要获取 WebView 在开始加载网页和网页加载完成时的时间戳,时间戳的差即为打开网页的时间。
WKWebView
<pre class="prettyprint hljs swift" deep="5" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; word-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">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)")
}
}
复制代码</pre>
UIWebView
<pre class="prettyprint hljs swift" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; word-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">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)")
}
}
复制代码</pre>
flutter_webview_plugin
<pre class="prettyprint hljs lua" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; word-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">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;
});
}
});
复制代码</pre>
为了使差异更明显,我们选择较为复杂的新浪首页 进行加载的对比,为了减小网络对加载速度的影响,我们让手机连接同一个网络,分别进行 10 次测试然后取平均值,另外,我们需要关闭 WebView 的缓存,防止缓存对加载速度产生影响:
<pre class="prettyprint hljs swift" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; word-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">private func delegateCache() {
let cache = URLCache.shared
cache.removeAllCachedResponses()
cache.diskCapacity = 0
cache.memoryCapacity = 0
}
复制代码</pre>
<pre class="prettyprint hljs swift" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; word-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">private func deleteWebCache() {
let websiteDataTypes: Set<String> = WKWebsiteDataStore.allWebsiteDataTypes()
let dateFrom = Date.init(timeIntervalSince1970: 0)
WKWebsiteDataStore.default().removeData(ofTypes: websiteDataTypes, modifiedSince: dateFrom) {
}
}
复制代码</pre>
<pre class="prettyprint hljs yaml" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; word-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">WebviewScaffold(
key: _scaffoldKey,
url: widget.url,
clearCache: true,
appCacheEnabled: false,
.
.
.
);
复制代码</pre>
下面使笔者进行 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,首先看之前测试时,连续打开十次新浪的内存情况:
image image image接着我们在看一下打开淘宝首页的内存情况
image |
|
从图上可以看出,WKWebView 在内存方面有很大的优势啊,UIWebView 的内存是真的伤啊,然后 debug 看了一下 flutter_webView,他使用的就是原生的 webView。
他相比较原生 WKWebView 的内存开销稍大一点,从测试表现来看,一般大个 30 MB 左右。
结论:内存 WKWebView > flutter_webview > UIWebView
HTML5 兼容性对比
可以在html5test 中对浏览器的兼容性进行评分,通过测试发现得分分别如下:
image |
|
因为 flutter 里使用的就是 WK,所以和原生的 WKWebView 一样都是 444 分,比 UIWebView 的 437 略胜一筹。
结论:兼容性 WKWebView = flutter_webview > UIWebView
喜欢的话可以点个赞+1:或关注多多支持哦 小编会经常给小伙伴们更新关于IOS当下热点。
另外小编给大家推荐一个iOS技术交流群:458839238!群内提供数据结构与算法、底层进阶、swift、逆向、整合面试题等免费资料
附上一份收集的各大厂面试题(附答案) ! 群文件直接获取
各大厂面试题
文章来源网络 如有侵权请联系小编删除
网友评论