背景
開發(fā)中 WebView是很常用的技術(shù)方案 相比native 也有著很明顯的一些優(yōu)點 如:
1泛啸、實現(xiàn)安卓 iOS的復(fù)用
2、不用發(fā)版 動態(tài)更新頁面
3朴读、節(jié)約native開發(fā)資源
......
但同時 也存在一些缺點 比較明顯的就是 加載速度比較慢 用戶體驗不如native
所以 提高WebView的加載速度 提升用戶體驗是避不開的問題
WebView加載速度優(yōu)化方案
一缅疟、WebView加載過程
想要優(yōu)化WebView加載速度 首先需要了解下網(wǎng)頁加載過程:
初始化webview -> 建立連接 -> 請求頁面 -> 下載數(shù)據(jù) -> 解析HTML -> 請求 js/css 資源 -> dom 渲染 -> 解析 JS 執(zhí)行 -> JS 請求數(shù)據(jù) -> 解析渲染 -> 下載渲染圖片
二还蹲、WebView優(yōu)化方案
1、提前初始化WebView
當(dāng)App打開時奔滑,默認是并不初始化瀏覽器內(nèi)核的艾岂;只有當(dāng)創(chuàng)建WebView實例的時候,才會創(chuàng)建WebView的基礎(chǔ)框架朋其。
所以與瀏覽器不同王浴,App中打開WebView的第一步并不是建立連接脆炎,而是啟動瀏覽器內(nèi)核。
提前初始化WebView可以節(jié)省這部分時間
提前初始化WebView分為兩種情況
① 剛啟動 還沒打開過WebView
可以初始化一個全局單例WebView 在APP剛啟動時就初始化 打開具體頁面是都復(fù)用這同一個WebView
這種方式存在的一個缺點就是如果用戶不打開WebView 會造成資源的浪費
② 每次打開WebView時 如果之前沒有打開過 把當(dāng)前WebView存到內(nèi)存中 下次打開 直接取出來使用
③ 對于確定性比較高的常用網(wǎng)頁 可以在啟動時直接保存到內(nèi)存 用戶打開時就可以直接顯示
2叼耙、預(yù)存HTML到本地
APP啟動時預(yù)存HTML到本地 打開WebView準(zhǔn)備加載HTML文件時 WKURLSchemeHandler 攔截請求資源判斷資源是否和本地資源一致(一致則返回本地資源文件腕窥,不一致則請求網(wǎng)絡(luò)資源)
這種預(yù)存方式不能處理Http、Https等常規(guī)scheme 本地資源不存在時 請求網(wǎng)絡(luò)資源時 可能需要主動轉(zhuǎn)換成http/https
- (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)urlSchemeTask {
self.holdUrlSchemeTasks[urlSchemeTask.description] = @(YES);
/// 優(yōu)先加載本地資源筛婉,本地沒有加載網(wǎng)絡(luò)資源化
NSString *urlString = urlSchemeTask.request.URL.absoluteString;
NSString *fileName = [urlString lastPathComponent];
NSString *markStrig = [NSString stringWithFormat:@"%@/",NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject];
NSRange range = [urlString rangeOfString:markStrig];
if (range.location != NSNotFound) {
fileName = [urlString substringFromIndex:range.location];
}
NSString *mainBundlePath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *htmlPath = [mainBundlePath stringByAppendingFormat:@"/"];
NSString *filePath = [htmlPath stringByAppendingFormat:@"%@",fileName];
NSFileManager *fileManager = [NSFileManager defaultManager];
/// 判斷文件是否存在
if ([fileManager fileExistsAtPath:filePath]) {
NSData *data = [NSData dataWithContentsOfFile:filePath];
NSURLResponse *response = [[NSURLResponse alloc] initWithURL:urlSchemeTask.request.URL MIMEType:@"text/html" expectedContentLength:data.length textEncodingName:nil];
[urlSchemeTask didReceiveResponse:response];
[urlSchemeTask didReceiveData:data];
[urlSchemeTask didFinish];
} else {
NSString *schemeUrl = urlSchemeTask.request.URL.absoluteString;
if ([schemeUrl hasPrefix:@"qekj"]) {
schemeUrl = [schemeUrl stringByReplacingOccurrencesOfString:@"qekj" withString:@"http"];
}
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:schemeUrl]];
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
NSNumber *number = self.holdUrlSchemeTasks[urlSchemeTask.description];
BOOL flag = number.boolValue;
if (flag == NO) {
return;
}
if (response) {
[urlSchemeTask didReceiveResponse:response];
} else {
NSURLResponse *response = [[NSURLResponse alloc] initWithURL:urlSchemeTask.request.URL MIMEType:@"未知類型" expectedContentLength:data.length textEncodingName:nil];
[urlSchemeTask didReceiveResponse:response];
}
[urlSchemeTask didReceiveData:data];
if (error) {
[urlSchemeTask didFailWithError:error];
} else {
[urlSchemeTask didFinish];
}
});
}];
[dataTask resume];
}
}
3簇爆、H5的css、js文件爽撒、圖片資源壓縮處理
這個需要H5同學(xué)幫助
H5的css入蛆、js文件壓縮方案
4、js硕勿、css哨毁、image等資源進行離線緩存
WKWebView是有緩存策略模式的 通常情況下 我們是關(guān)閉緩存的 不然可能會出現(xiàn)數(shù)據(jù)不能及時更新的問題
如果開啟了本地緩存配置 建議H5鏈接增加一個類似于版本號的標(biāo)識 如果內(nèi)容有更新 則版本號+1 WKWebView的緩存是通過urlString來判斷是否需要重新加載 版本號變化 會認為是新的網(wǎng)頁 則會重新加載
參考
支付寶移動端動態(tài)化方案實踐
Web離線技術(shù)
WKURLSchemeHandler協(xié)議優(yōu)化HTML加載速度
iOS WebView的性能、體驗優(yōu)化
移動 H5 首屏秒開優(yōu)化方案探討
iOS html5使用緩存并及時更新方案總結(jié)