乔帮主的遗产IOS面试专题

WKWebView和UIWebView对比

2018-08-19  本文已影响0人  奋斗的蝼蚁

WKWebView和UIWebView

UIWebView自iOS2就有,WKWebView从iOS8才有,毫无疑问WKWebView将逐步取代笨重的UIWebView。通过简单的测试即可发现UIWebView占用过多内存,且内存峰值更是夸张。WKWebView网页加载速度也有提升,但是并不像内存那样提升那么多。下面列举一些其它的优势:

UIWebView

OC调用JS

- (nullable NSString *)stringByEvaluatingJavaScriptFromString:

JS调用OC

让Native 代码拦截, - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest:)request navigationType:(UIWebViewNavigationType)navigationType

方案中进行拦截处理。

WKWebView

OC调用JS

- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^_Nullable)(_Nullable id,NSError * _Nullable error))completionHandler;

WKWebView 本身提供一个方法进行处理JS代码

- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;

JS调用OC

在JS端的操作

window.webkit.messageHandlers.<方法名>.postMessage(<数据>)

在OC中的处理方法

- (void)addScriptMessageHandler:(id<WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;

具体如下

//设置addScriptMessageHandler与name.并且设置<WKScriptMessageHandler>协议与协议方法
[[_webView configuration].userContentController addScriptMessageHandler:self name:@"方法名"];

//WKScriptMessageHandler协议方法
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    //code
}

如果你在self的dealloc打个断点,会发现self没有释放,这显示是不行的。
思路是另外创建一个代理对象,然后通过代理对象回调指定的self。

https://github.com/CheeryLau/WKWebView

WKWebView 坑

WKWebView 白屏问题

WKWevView Cookie 问题

WKWebView NSURLProtocol问题

由于 WKWebView 在独立进程里执行网络请求。一旦注册 http(s) scheme 后,网络请求将从 Network Process 发送到 App Process,这样 NSURLProtocol 才能拦截网络请求。在 webkit2 的设计里使用 MessageQueue 进行进程之间的通信,Network Process 会将请求 encode 成一个 Message,然后通过 IPC 发送给 App Process。出于性能的原因,encode 的时候 HTTPBody 和 HTTPBodyStream 这两个字段被丢弃掉了(参考苹果源码:
https://github.com/WebKit/webkit/blob/fe39539b83d28751e86077b173abd5b7872ce3f9/Source/WebKit2/Shared/mac/WebCoreArgumentCodersMac.mm#L61-L88 及bug report: <WKWebView does not fully support custom NSURLProtocol>)。
测试发现一旦打开ATS开关:Allow Arbitrary Loads 选项设置为NO,同时通过 registerSchemeForCustomProtocol 注册了 http(s) scheme,WKWebView 发起的所有 http 网络请求将被阻塞(即便将Allow Arbitrary Loads in Web Content 选项设置为YES);
WKWebView 可以注册 customScheme, 比如 dynamic://, 因此希望使用离线功能又不使用 post 方式的请求可以通过 customScheme 发起请求,比如 dynamic://http://www.dynamicalbumlocalimage.com/,然后在 app 进程 NSURLProtocol 拦截这个请求并加载离线数据。不足:使用 post 方式的请求该方案依然不适用,同时需要 H5 侧修改请求 scheme 以及 CSP 规则

WKWebView loadRequest 问题

//同样是由于进程间通信性能问题,HTTPBody字段被丢弃
 [request setHTTPMethod:@"POST"];
 [request setHTTPBody:[@"bodyData" dataUsingEncoding:NSUTF8StringEncoding]];
 [wkwebview loadRequest: request]

WKWebView 页面样式问题

WKWebView 截屏问题

WkWebView crash 问题

WKWebView和UIWebView 的区别

WKWebView 更快(占用内存可能只有 UIWebView 的1/3~1/4),没有缓存,更为细致地拆分了 UIWebViewDelegate 中的方法。
想要了解更多关于 WKWebView 的特性的,可以自行 Google,这里你可以简单地把它当做是轻量级的 UIWebView

网络优化

WebViewJavascriptBridge

https://tech.meituan.com/WebViewPerf.html
https://zhuanlan.zhihu.com/p/24990222
https://github.com/CheeryLau/WKWebView

上一篇下一篇

猜你喜欢

热点阅读