iOS 提高WebView加載速度優(yōu)化方案

背景

開發(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)存中 下次打開 直接取出來使用

根據(jù)url取出WebView

③ 對于確定性比較高的常用網(wǎng)頁 可以在啟動時直接保存到內(nèi)存 用戶打開時就可以直接顯示
根據(jù)url預(yù)加載WebView

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];
    }
}

處理自定義請求的方案

scheme替換

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)頁 則會重新加載
WKWebView默認緩存策略

參考

支付寶移動端動態(tài)化方案實踐
Web離線技術(shù)
WKURLSchemeHandler協(xié)議優(yōu)化HTML加載速度
iOS WebView的性能、體驗優(yōu)化
移動 H5 首屏秒開優(yōu)化方案探討
iOS html5使用緩存并及時更新方案總結(jié)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末源武,一起剝皮案震驚了整個濱河市扼褪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌粱栖,老刑警劉巖话浇,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異闹究,居然都是意外死亡幔崖,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門渣淤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赏寇,“玉大人,你說我怎么就攤上這事价认⌒岫ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵用踩,是天一觀的道長渠退。 經(jīng)常有香客問我,道長捶箱,這世上最難降的妖魔是什么智什? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮丁屎,結(jié)果婚禮上荠锭,老公的妹妹穿的比我還像新娘。我一直安慰自己晨川,他們只是感情好证九,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布删豺。 她就那樣靜靜地躺著,像睡著了一般愧怜。 火紅的嫁衣襯著肌膚如雪呀页。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天拥坛,我揣著相機與錄音蓬蝶,去河邊找鬼。 笑死猜惋,一個胖子當(dāng)著我的面吹牛丸氛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播著摔,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼缓窜,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了谍咆?” 一聲冷哼從身側(cè)響起禾锤,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎摹察,沒想到半個月后恩掷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡港粱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年螃成,在試婚紗的時候發(fā)現(xiàn)自己被綠了旦签。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片查坪。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖宁炫,靈堂內(nèi)的尸體忽然破棺而出偿曙,到底是詐尸還是另有隱情,我是刑警寧澤羔巢,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布望忆,位于F島的核電站,受9級特大地震影響竿秆,放射性物質(zhì)發(fā)生泄漏启摄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一幽钢、第九天 我趴在偏房一處隱蔽的房頂上張望歉备。 院中可真熱鬧,春花似錦咐吼、人聲如沸齐饮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽龟再。三九已至书闸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間利凑,已是汗流浹背浆劲。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留哀澈,地道東北人梳侨。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像日丹,于是被迫代替她去往敵國和親走哺。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容