本文主要测试了目前iOS开发中,主要使用的UIWebView和WKWebView两个webview和JS之间的交互性能。区分目前主流开发中JS和Native之间的交互方式,主要测试了相互调用的响应时间差。
测试环境:
iPhone6s Plus iOS 11.4.1
MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)
处理器:2.3 GHz Intel Core i5
内存:8 GB 2133 MHz LPDDR3
MacOS High Sierra 版本:10.13.6
JS调用Native性能测试
使用UIWebView的情况
JS调用Native的方式:使用JSExport协议注入JS对象 或者 使用第三方库WebViewJavascriptBridge 两种方式:
方式1:JSExport协议注入JS对象
Native端 注入jsBridge对象,实现JSExport协议方法SendAppEvent接受JS调用。
在SendAppEvent开始,添加如下代码打印系统时间:
NSTimeInterval interval = [[NSDate date] timeIntervalSince1970] * 1000;
NSLog(@"call start = %f", interval);
JS中执行下面代码,在Console中打印系统时间:
var timestamp3 =new Date().getTime();
console.log(timestamp3);
jsBridge.sendAppEvent()
UIWebView分别加载两个站点,进行了10次调用统计如下:
方式2:使用第三方库WebViewJavascriptBridge
WebViewJavascriptBridge参考该库提供的方式封装一个JSLib,测试方式类似,统计结果如下:
结果分析:
JSExport方式的调用时间大概在2.6ms,而WebViewJavascriptBridge方式需要30ms的样子,尽管都时间非常短,人感觉不到。但是数字比较的话,前者比后者要快10多倍。
主要原因分析:JSExport方式是通过JavaScriptCore系统框架注入JS对象,根据调用方式推断是“直接调用”,消耗的时间主要在JS和Native转换上。而WebViewJavascriptBridge的源代码实现,是通过协议回调的时候拦截的。
使用WKWebView的情况
JS调用Native的方式:使用WKWebViewConfiguration对象的addScriptMessageHandler方法注入JS对象 或者 使用第三方库WebViewJavascriptBridge 两种方式:
方式1:WKWebViewConfiguration对象注入JS对象
Native端 注入jsBridge对象,实现didReceiveScriptMessage协议接受JS调用。
在didReceiveScriptMessage开始,添加如下代码打印系统时间:
NSTimeInterval interval = [[NSDate date] timeIntervalSince1970] * 1000;
NSLog(@"call start = %f", interval);
JS中执行下面代码,在Console中打印系统时间:
var timestamp3 =new Date().getTime();
console.log(timestamp3);
webkit.messageHandlers.jsBridge.postMessage("")
WKWebView分别加载两个站点,进行了10次调用统计如下:
方式2:使用第三方库WebViewJavascriptBridge
WebViewJavascriptBridge参考该库提供的方式封装一个JSLib,测试方式类似,统计结果如下:
结果分析:
WKWebViewConfiguration方式的调用不是很稳定,平均时间大概在19ms,而WebViewJavascriptBridge方式需要30ms的样子,和UIWebView相似。仅就数字比较的话,前者比后者要快1/3倍。
主要原因分析:WKWebViewConfiguration方式是通过postMessage异步消息调用,中间不稳定消耗的时间主要在消息响应。而WebViewJavascriptBridge的源代码实现,也是通过协议回调的时候拦截的。
Native调用JS性能测试
Native调用JS的方式都是通过UIWebView和WKWebView自带的方法来调用的,
UIWebView方式:调用stringByEvaluatingJavaScriptFromString
Native端添加如下代码,在Console中获取打印的系统时间:
NSTimeInterval interval = [[NSDate date] timeIntervalSince1970] * 1000;
NSLog(@"share start = %f", interval);
[_webView stringByEvaluatingJavaScriptFromString:@"var timestamp3=new Date().getTime();console.log(timestamp3);"];
测试结果统计如下:
WKWebView方式:调用evaluateJavaScript
Native端添加如下代码,在Console中获取打印的系统时间:
NSTimeInterval interval = [[NSDate date] timeIntervalSince1970] * 1000;
NSLog(@"share start = %f", interval);
[_webView evaluateJavaScript:@"var timestamp3 =new Date().getTime();console.log(timestamp3);" completionHandler:^(id _Nullable data, NSError * _Nullable error) {
}];
测试结果统计如下:
测试结果:
根据以上测试结果,UIWebView的JSExport协议注入JS对象方式是响应时间最短的,比较推荐。
UIWebView或WKWebView的选择后续补充文章来分析(敬请期待)
限制条件:
本文只是简单测试调用和响应的时间差,调用时传递的“空字符串”,对“长字符串”调用未测试。