WKWebView和UIWebView
UIWebView自iOS2就有,WKWebView從iOS8才有警医,毫無(wú)疑問(wèn)WKWebView將逐步取代笨重的UIWebView。通過(guò)簡(jiǎn)單的測(cè)試即可發(fā)現(xiàn)UIWebView占用過(guò)多內(nèi)存,且內(nèi)存峰值更是夸張。WKWebView網(wǎng)頁(yè)加載速度也有提升孽亲,但是并不像內(nèi)存那樣提升那么多。下面列舉一些其它的優(yōu)勢(shì):
- 更多的支持HTML5的特性
- 官方宣稱(chēng)的高達(dá)60fps的滾動(dòng)刷新率以及內(nèi)置手勢(shì)
- Safari相同的JavaScript引擎
- 將UIWebViewDelegate與UIWebView拆分成了14類(lèi)與3個(gè)協(xié)議(官方文檔說(shuō)明)
- 另外用的比較多的肄扎,增加加載進(jìn)度屬性:estimatedProgress
UIWebView
OC調(diào)用JS
- (nullable NSString *)stringByEvaluatingJavaScriptFromString:
JS調(diào)用OC
讓Native 代碼攔截墨林, - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest:)request navigationType:(UIWebViewNavigationType)navigationType
方案中進(jìn)行攔截處理赁酝。
WKWebView
OC調(diào)用JS
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^_Nullable)(_Nullable id,NSError * _Nullable error))completionHandler;
WKWebView 本身提供一個(gè)方法進(jìn)行處理JS代碼
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;
JS調(diào)用OC
在JS端的操作
window.webkit.messageHandlers.<方法名>.postMessage(<數(shù)據(jù)>)
在OC中的處理方法
- (void)addScriptMessageHandler:(id<WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;
具體如下
//設(shè)置addScriptMessageHandler與name.并且設(shè)置<WKScriptMessageHandler>協(xié)議與協(xié)議方法
[[_webView configuration].userContentController addScriptMessageHandler:self name:@"方法名"];
//WKScriptMessageHandler協(xié)議方法
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
//code
}
如果你在self的dealloc打個(gè)斷點(diǎn)犯祠,會(huì)發(fā)現(xiàn)self沒(méi)有釋放,這顯示是不行的酌呆。
思路是另外創(chuàng)建一個(gè)代理對(duì)象衡载,然后通過(guò)代理對(duì)象回調(diào)指定的self。
WKWebView 坑
WKWebView 白屏問(wèn)題
WKWevView Cookie 問(wèn)題
WKWebView NSURLProtocol問(wèn)題
- WKWebView 在獨(dú)立于app進(jìn)程之外的進(jìn)程中執(zhí)行網(wǎng)絡(luò)請(qǐng)求隙袁,請(qǐng)求數(shù)據(jù)不經(jīng)過(guò)主進(jìn)程痰娱,因此弃榨,在WKWebView上直接使用NSURLProtocol無(wú)法攔截請(qǐng)求。
- post 請(qǐng)求body 數(shù)據(jù)被清空(encode的時(shí)候HTTPBody和HTTPBodyStream 這兩個(gè)字段被丟棄了)
由于 WKWebView 在獨(dú)立進(jìn)程里執(zhí)行網(wǎng)絡(luò)請(qǐng)求梨睁。一旦注冊(cè) http(s) scheme 后鲸睛,網(wǎng)絡(luò)請(qǐng)求將從 Network Process 發(fā)送到 App Process,這樣 NSURLProtocol 才能攔截網(wǎng)絡(luò)請(qǐng)求坡贺。在 webkit2 的設(shè)計(jì)里使用 MessageQueue 進(jìn)行進(jìn)程之間的通信官辈,Network Process 會(huì)將請(qǐng)求 encode 成一個(gè) Message,然后通過(guò) IPC 發(fā)送給 App Process。出于性能的原因遍坟,encode 的時(shí)候 HTTPBody 和 HTTPBodyStream 這兩個(gè)字段被丟棄掉了(參考蘋(píng)果源碼:
https://github.com/WebKit/webkit/blob/fe39539b83d28751e86077b173abd5b7872ce3f9/Source/WebKit2/Shared/mac/WebCoreArgumentCodersMac.mm#L61-L88 及bug report: <WKWebView does not fully support custom NSURLProtocol>)拳亿。
- 對(duì)ATS支持不足
測(cè)試發(fā)現(xiàn)一旦打開(kāi)ATS開(kāi)關(guān):Allow Arbitrary Loads 選項(xiàng)設(shè)置為NO,同時(shí)通過(guò) registerSchemeForCustomProtocol 注冊(cè)了 http(s) scheme愿伴,WKWebView 發(fā)起的所有 http 網(wǎng)絡(luò)請(qǐng)求將被阻塞(即便將Allow Arbitrary Loads in Web Content 選項(xiàng)設(shè)置為YES)肺魁;
WKWebView 可以注冊(cè) customScheme, 比如 dynamic://, 因此希望使用離線(xiàn)功能又不使用 post 方式的請(qǐng)求可以通過(guò) customScheme 發(fā)起請(qǐng)求,比如 dynamic://http://www.dynamicalbumlocalimage.com/隔节,然后在 app 進(jìn)程 NSURLProtocol 攔截這個(gè)請(qǐng)求并加載離線(xiàn)數(shù)據(jù)鹅经。不足:使用 post 方式的請(qǐng)求該方案依然不適用,同時(shí)需要 H5 側(cè)修改請(qǐng)求 scheme 以及 CSP 規(guī)則
WKWebView loadRequest 問(wèn)題
- 在WKWebView 上通過(guò)loadRequ發(fā)起的post請(qǐng)求body數(shù)據(jù)被丟失
//同樣是由于進(jìn)程間通信性能問(wèn)題怎诫,HTTPBody字段被丟棄
[request setHTTPMethod:@"POST"];
[request setHTTPBody:[@"bodyData" dataUsingEncoding:NSUTF8StringEncoding]];
[wkwebview loadRequest: request]
WKWebView 頁(yè)面樣式問(wèn)題
WKWebView 截屏問(wèn)題
WkWebView crash 問(wèn)題
WKWebView和UIWebView 的區(qū)別
WKWebView 更快(占用內(nèi)存可能只有 UIWebView 的1/3~1/4)瞬雹,沒(méi)有緩存,更為細(xì)致地拆分了 UIWebViewDelegate 中的方法刽虹。
想要了解更多關(guān)于 WKWebView 的特性的酗捌,可以自行 Google,這里你可以簡(jiǎn)單地把它當(dāng)做是輕量級(jí)的 UIWebView
網(wǎng)絡(luò)優(yōu)化
WebViewJavascriptBridge
https://tech.meituan.com/WebViewPerf.html
https://zhuanlan.zhihu.com/p/24990222
https://github.com/CheeryLau/WKWebView