一、问题
使用h5来实现某些界面,有时是方便而且快捷的,但是h5界面在iOS设备上的表现始终有些迟顿感,比如我们在h5界面上布一个button并用js来接收事件,其反应总会让人有一种卡顿的感觉。
对此,我们使用计时的方式,各种从h5传事件回原生的方式进行统计。有以下方式:1、UIWebView使用js接收事件;2、UIWebView使用JSCore接收事件;3、WKWebView使用ScriptDelegate接收事件。4、直接获取点击,然后通过elementFromPoint来计算元素,然后在oc中写事件响应。
二、过程
1、使用UIWebView原生js
html中:
js 事件:
function inwebAction() {
let date = new Date();
console.log("inweb:" + date.getTime()/1000);
alert("hello");
}
为了测量该方法的反应时间,我们使用alert来弹出一个时间: alert("inweb:" + date.getTime()/1000);
给webView增加一个点击手势,在点击时记录时间:
self.web = [[UIWebView alloc] initWithFrame:self.view.bounds];
self.web.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
[self.view addSubview:self.web];
NSLog(@"tap time: %.3f", [[NSDate date] timeIntervalSince1970]);
测出的反应时间:1513235863.718 - 1513235864.101 = 0.38
1513235976.569 - 1513235976.921 = 0.35
1513236032.943 - 1513236033.296 = 0.35
2、使用jscore来接收事件
在oc中使用jscore来写入一个回调方法:
JSContext *ctx = [self.web valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
ctx[@"actionJsCore"] = ^() {
NSLog(@"tap time: %.3f", [[NSDate date] timeIntervalSince1970]);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"点击了" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
[alert show];
};
然后在js中调用这个方法:
测出反应时间: 1513236281.103 - 1513236281.456 = 0.35
1513236302.359 - 1513236302.712 = 0.353
1513236332.141 - 1513236332.494 = 0.353
跟上一个方法差不多。
3、使用wkwebview来处理事件
html里:
function usewk() {
// AppModel是我们所注入的对象
window.webkit.messageHandlers.AppModel.postMessage({body: 'call js confirm in js'});
}
oc中处理事件:
[self.wkweb.configuration.userContentController addScriptMessageHandler:self name:@"AppModel"];
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
if ([message.name isEqualToString:@"AppModel"]) {
NSLog(@"tap time: %.3f", [[NSDate date] timeIntervalSince1970]);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"点击了" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
[alert show];
}
}
结果:1513236537.402 - 1513236537.763 = 0.361
1513236584.727 - 1513236585.083 = 0.356
1513236625.780 - 1513236626.136 = 0.356
似乎,wk中处理比uiwebview还要慢一些。
4、直接在oc中处理
直接获取点击手势的位置,然后通过该位置来获取被点击的元素:
CGPoint pt = [tap locationInView:self.web];
NSString *js = [NSString stringWithFormat:@"window.document.elementFromPoint(%f, %f).id", pt.x, pt.y-20];
NSString *value = [self.web stringByEvaluatingJavaScriptFromString:js];
if ([value isEqualToString:@"oc"]) {
NSLog(@"tap time: %.3f", [[NSDate date] timeIntervalSince1970]);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"点击了" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
[alert show];
}
实测这种方式的时间接近于原生。