前言
接到一個提升App里h5的加載速度優化的問題,參考了很多文章后決定從webview緩存池、并行加載開始
1、統計從的耗時
點擊入口->controller創建(init)->設置訪問的url地址->調用webview的loadRequest->webview回調start->webview回調finish
統計發現,在調用點擊入口到loadRequest這個過程耗費了0.5s左右,
1、于是參考VasSonic在Controller初始化Init時就調用初始好Webview,后來改成在APP啟動時就創建一個Webview的緩存池,這樣在頁面一開始時就已經有webkit內核初始化好的Webview
2、在設置好url后立馬調用Webview的loadRequest
但是這個過程中遇到了幾個問題,在使用Webview緩存池使用Webview時會有Webview留存上次訪問棧的問題,同時在下次請求時還會先展示上次請求過的內容,具體解決辦法如下:
清空Webview的緩存棧:執行js方法
[webView evaluateJavaScript@" window.location.replace( 'https://www.baidu.com' )"]
刪除上次訪問的內容
[webView evaluateJavaScript@"window.document.body.remove();"]
清空sessionStorage里的內容
[webView evaluateJavaScript@"window.sessionStorage.removeItem(\"token\");"]
清空locationStorage里的內容
[webView evaluateJavaScript@"window.localStorage.removeItem(\"token\");"]
清空cookie里的內容
[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里的內容
- (void)test_clearBody;
/// 替換url請求,清空訪問棧
- (void)test_replaceUrl:(NSString *)url;
/// 清除LocalStorage里的內容
- (void)test_deleLocalStorage:(NSString *)key;
/// 清除SessionStorage里的內容
- (void)test_deleSessionStorage:(NSString *)key;
/// 清除cookie里的內容
- (void)test_deleCookie:(NSString *)key path:(NSString *)path;
@end
NS_ASSUME_NONNULL_END
WKWebView+Test.m
#import "WKWebView+Test.h"
@implementation WKWebView (Test)
// 刪除webview里的內容
- (void)test_clearBody{
[self evaluateJavaScript@"window.document.body.remove();"]
}
/// 替換url請求,清空訪問棧
- (void)test_replaceUrl:(NSString *)url {
if ([url.lowercaseString hasPrefix:@"http"]) {
NSString *href = [NSString stringWithFormat:@"window.location.replace('%@')",url];
[self evaluateJavaScript:href completionHandler:nil];
}
}
/// 清除LocalStorage里的內容
- (void)test_deleLocalStorage:(NSString *)key {
NSString *text = [NSString stringWithFormat:@"window.localStorage.removeItem(\"%@\",\"\");",key];
[self evaluateJavaScript:text completionHandler:nil];
}
/// 清除SessionStorage里的內容
- (void)test_deleSessionStorage:(NSString *)key {
NSString *text = [NSString stringWithFormat:@"window.sessionStorage.removeItem(\"%@\",\"\");",key];
[self evaluateJavaScript:text completionHandler:nil];
}
/// 清除cookie里的內容
- (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
針對
WKWebview
請求網絡時cookie丟失的問題,對重定向的請求都重新將cookie讀取出來放入到請求的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;
}
延伸閱讀: