前言
接到一個(gè)提升App里h5的加載速度優(yōu)化的問(wèn)題,參考了很多文章后決定從webview緩存池、并行加載開(kāi)始
1、統(tǒng)計(jì)從的耗時(shí)
點(diǎn)擊入口->controller創(chuàng)建(init)->設(shè)置訪問(wèn)的url地址->調(diào)用webview的loadRequest->webview回調(diào)start->webview回調(diào)finish
統(tǒng)計(jì)發(fā)現(xiàn),在調(diào)用點(diǎn)擊入口到loadRequest這個(gè)過(guò)程耗費(fèi)了0.5s左右,
1、于是參考VasSonic在Controller初始化Init時(shí)就調(diào)用初始好Webview,后來(lái)改成在APP啟動(dòng)時(shí)就創(chuàng)建一個(gè)Webview的緩存池,這樣在頁(yè)面一開(kāi)始時(shí)就已經(jīng)有webkit內(nèi)核初始化好的Webview
2、在設(shè)置好url后立馬調(diào)用Webview的loadRequest
但是這個(gè)過(guò)程中遇到了幾個(gè)問(wèn)題,在使用Webview緩存池使用Webview時(shí)會(huì)有Webview留存上次訪問(wèn)棧的問(wèn)題,同時(shí)在下次請(qǐng)求時(shí)還會(huì)先展示上次請(qǐng)求過(guò)的內(nèi)容,具體解決辦法如下:
清空Webview的緩存棧:執(zhí)行js方法
[webView evaluateJavaScript@" window.location.replace( 'https://www.baidu.com' )"]
刪除上次訪問(wèn)的內(nèi)容
[webView evaluateJavaScript@"window.document.body.remove();"]
清空sessionStorage里的內(nèi)容
[webView evaluateJavaScript@"window.sessionStorage.removeItem(\"token\");"]
清空l(shuí)ocationStorage里的內(nèi)容
[webView evaluateJavaScript@"window.localStorage.removeItem(\"token\");"]
清空cookie里的內(nèi)容
[webView evaluateJavaScript:@"document.cookie = \"token=xxx;expires=Thu, 01 Jan 1970 00:00:01 GMT;path=/;\""]
完整處理分類:
WKWebView+Test.h
#import <WebKit/WebKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface WKWebView (Test)
// 刪除webview里的內(nèi)容
- (void)test_clearBody;
/// 替換url請(qǐng)求,清空訪問(wèn)棧
- (void)test_replaceUrl:(NSString *)url;
/// 清除LocalStorage里的內(nèi)容
- (void)test_deleLocalStorage:(NSString *)key;
/// 清除SessionStorage里的內(nèi)容
- (void)test_deleSessionStorage:(NSString *)key;
/// 清除cookie里的內(nèi)容
- (void)test_deleCookie:(NSString *)key path:(NSString *)path;
@end
NS_ASSUME_NONNULL_END
WKWebView+Test.m
#import "WKWebView+Test.h"
@implementation WKWebView (Test)
// 刪除webview里的內(nèi)容
- (void)test_clearBody{
[self evaluateJavaScript@"window.document.body.remove();"]
}
/// 替換url請(qǐng)求,清空訪問(wèn)棧
- (void)test_replaceUrl:(NSString *)url {
if ([url.lowercaseString hasPrefix:@"http"]) {
NSString *href = [NSString stringWithFormat:@"window.location.replace('%@')",url];
[self evaluateJavaScript:href completionHandler:nil];
}
}
/// 清除LocalStorage里的內(nèi)容
- (void)test_deleLocalStorage:(NSString *)key {
NSString *text = [NSString stringWithFormat:@"window.localStorage.removeItem(\"%@\",\"\");",key];
[self evaluateJavaScript:text completionHandler:nil];
}
/// 清除SessionStorage里的內(nèi)容
- (void)test_deleSessionStorage:(NSString *)key {
NSString *text = [NSString stringWithFormat:@"window.sessionStorage.removeItem(\"%@\",\"\");",key];
[self evaluateJavaScript:text completionHandler:nil];
}
/// 清除cookie里的內(nèi)容
- (void)test_deleCookie:(NSString *)key path:(NSString *)path {
NSString *text = [NSString stringWithFormat:@"document.cookie = \"%@=empty;expires=Thu, 01 Jan 1970 00:00:01 GMT;path=%@;\"",key,path];
[self evaluateJavaScript:text completionHandler:nil];
}
@end
針對(duì)
WKWebview請(qǐng)求網(wǎng)絡(luò)時(shí)cookie丟失的問(wèn)題,對(duì)重定向的請(qǐng)求都重新將cookie讀取出來(lái)放入到請(qǐng)求的header的cookie里
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
[self redirectRequest: navigationAction.request];
decisionHandler(WKNavigationActionPolicyAllow);
}
- (NSURLRequest *)redirectRequest:(NSURLRequest *)request
{
NSMutableURLRequest *redirectRequest;
if ([request isKindOfClass:[NSMutableURLRequest class]]) {
redirectRequest = (NSMutableURLRequest *)request;
} else {
redirectRequest = [request mutableCopy];
}
NSArray<NSHTTPCookie *> *cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies;
NSDictionary *cookieHeaders = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
if (originCookies.count) {
NSMutableDictionary *redirectHeaders = request.allHTTPHeaderFields.mutableCopy;
[redirectHeaders setValuesForKeysWithDictionary:cookieHeaders];
redirectRequest.allHTTPHeaderFields = redirectHeaders;
}
return redirectRequest;
}
延伸閱讀: