日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS之深入解析WKWebView加载的生命周期与代理方法

發布時間:2024/5/21 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS之深入解析WKWebView加载的生命周期与代理方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、前言

  • 從 WebView 開始加載一條請求,到頁面完整呈現這一過程發生了什么?無論是做 WebView 性能優化還是異常問題監控與排查,都離不開對WKWebView加載的生命周期與代理方法的剖析。
  • 在 WebKit 源碼的調試基礎之上, 結合 iOS 端 WKWebView 的 WKNavigationDelegate 代理方法,站在移動端的視角深入分析 WKWebView 網絡請求加載的生命周期流程。
  • WebKit 源碼的調試,請參考我之前的博客:iOS之深入解析WKWebView的WebKit源碼調試與分析。

二、 WebKit 加載框架

  • 在iOS之深入解析WKWebView的WebKit源碼調試與分析驗證了 WebKit 三大進程工作模型,并簡述了三大進程的主要職責。UIProcess、WebContent、NetworkProces 三大進程間通信關系圖如下:

  • UIProcess、WebContent、NetworkProces 進程關系分析:
    • NetworkProcess進程:主要負責網絡請求加載,所有的網頁共享這一進程。與原生網絡請求開發一致,NetworkProcess 也是通過封裝的 NSURLSession 發起并管理網絡請求的。但不同的是,這一過程中有較多的網絡進度的回調工作以及各類網絡協議管理,比如資源緩存協議、HSTS 協議、cookie 管理協議等。
    • WebContent進程:主要負責頁面資源的管理,包含前進后退歷史,pageCache,頁面資源的解析、渲染。并把該進程中的各類事件通過代理方式通知給 UIProcess。
    • UIProcess進程:主要負責與 WebContent 進行交互,與 APP 在同一進程中,可以進行 WebView 的功能配置,并接收來自 WebContent 進程的各類消息,配合業務代碼執行任務的決策,例如是否發起請求,是否接受響應等。

三、WebKit 加載流程

  • 使用如下方法,從 UIProcess 層通過 loadReqeust 方法發起頁面加載請求(此處 request 只能是 get 請求,如果配置為 post 請求,WebKit 內核基于性能考慮,在跨進程傳輸時,會將 body 數據丟棄,導致異常):
[self.webView loadRequest:request];
  • 通過跟蹤 WebKit 源碼,我們提取核心步驟如下:
    • UIProcess 中的 loadRequest 首先會觸發 NetworkProcess 進程創建,然后通過進程間通信的方式將 request 發送給 NetworkProcess 進程進行 preconnect 預鏈接操作,通過網絡三次握手建立 TCP 鏈接,以便加快后續網絡資源請求速度。
    • UIProcess 通過進程間通信的方式將 request 發送給 WebContent 進程,WebContent 進程創建 DocumentLoader 加載器加載網絡請求,并取消上個頁面的所有還在加載的請求,然后通過字典綁定當前頁面ID與創建好的 NetworkProcss 進程(便于服務端數據返回時,查找數據回填所對應的頁面),最終將請求交付給 NetworkProcess 中的 NSURLSession 進行處理。
    • NetworkProcess 通過 NSURLSession 復用之前 preconnect 預鏈接,繼續進行網絡加載,此時等待網絡請求返回,網絡層會繼續將數據通過進程間通信方式傳輸給 WebContent 進程進行處理,開始流式進行數據解析,一邊接收一邊處理,進行詞法分析、語法分析,并在這一過程中加載解析出來的 js、css、圖片、字體等子資源,最終動態的生成(DOM 樹與 CSSOM 樹合成)渲染樹,在這一過程中,每次接受到新數據導致渲染樹有變更后,就會觸發一次 checkAndDispatchDidReachVisuallyNonEmptyState 方法,檢查當前頁面是否達到上屏狀態,若達到上屏狀態就進行上屏渲染。
  • 達到上屏狀態的條件如下:
    • 如果返回的 data 是普通文本文字,或返回的數據中包含普通文本文字,那只需要達到非空 200 字節即可以觸發上屏渲染;
    • 如果返回的 data 是圖片資源類,則判斷像素大小 > 32*32,即可觸發上屏渲染;
    • 如果不滿足以上條件,對于主文檔,判斷后面是否繼續接收數據,如果不繼續,則觸發上屏渲染;如后續還有數據,則循環上述流程直至觸發上屏。渲染完成,整個加載過程結束。
  • WebKit 加載流程如下:

四、WebKit 加載生命周期代理方法

① WKNavigationDelegate 方法
@protocol WKNavigationDelegate <NSObject>@optional// 請求之前,決定是否要跳轉:用戶點擊網頁上的鏈接,需要打開新頁面時,將先調用這個方法。- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler; // 頁面開始加載時調用- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation; // 接收到響應數據后,決定是否跳轉- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler; // 主機地址被重定向時調用- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation; // 當開始加載主文檔數據失敗時調用- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error; // 當內容開始返回時調用- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation; // 頁面加載完畢時調用- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation; // 當主文檔已committed時,如果發生錯誤將進行調用- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error; // 如果需要證書驗證,進行驗證,一般使用默認證書策略即可 - (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *__nullable credential))completionHandler; // 9.0才能使用,web內容處理中斷時會觸發,可針對該情況進行reload操作,可解決部分白屏問題 - (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView NS_AVAILABLE(10_11, 9_0); @end
② 深入理解 WKNavigationDelegate 方法
  • WKNavigationDelegate 代理方法的調用流程如下:

  • decidePolicyForNavigationAction 剖析
    • 如上文的網頁加載流程,當 WebContent 即將創建 DocumentLoader 加載器時,會首先觸發 decidePolicyForNavigationAction 代理方法。如果我們選擇 cancel,那么瀏覽內核會完全忽略這一操作,后續也不再繼續執行其他操作,可以放心的使用 cancel 取消掉我們不想加載的主文檔請求,而無需擔憂任何異常。
    • 但當選擇 alllow 后,會進入一個稍微復雜的邏輯判斷,內核代碼首先判斷該該鏈接是否是 universalLink 類型的鏈接,如果判斷是 universalLink 類型的鏈接,會嘗試去調起三方 app,如果能調起,則會 cancel 當前請求,否則才會走到正常的網絡加載邏輯(如果需要統計 universalLink 調起情況與或建設屏蔽能力,可以再仔細閱讀該處源碼)。
  • didStartProvisionalNavigation 理解
    • decidePolicyForNavigationAction 方法中選擇 allow 并且判斷為非 universalLink 鏈接后,會立即觸發 didStartProvisionalNavigation 方法,表示即將開始加載主文檔。這個方法看似只是對 decidePolicyForNavigationAction 方法的確認,但是值得思考的問題是方法名中的 Provisional 究竟是什么意思。
    • 其實,頁面開始頁面加載后為了更好的區分加載的各階段,會將網絡加載的初始階段命名為臨時狀態,此時的頁面是不會記入歷史的,直到接收到首個數據包,才會對當前頁面進行 committed 提交,并觸發didCommitNavigation 方法通知 UIProcess 進程該事件,同時將網絡 data 提交給 WebContent 進行渲染樹生成。可由此引申出下一個問題,即 didFailProvisionalNavigation 與 didFailNavigation 的關系。
  • didFailProvisionalNavigation 與 didFailNavigation 的分別在什么時候執行?它們之間有什么關系?
    • 當 NetworkProcess 進程發生網絡錯誤時,錯誤首先由 NSURLSession 回調到 WebContent 層。
    • WebContent 會判斷當前主文檔加載狀態,如果處于臨時態,則錯誤會回調給 didFailProvisionalNavigation 方法;如果處于提交態,則錯誤會回調給 didFailNavigation 方法。

  • didFinishNavigation 究竟什么時候執行?與頁面上屏是否有關?
    • 在上面的描述中,我們已經理解了 NetworkProcess 層也是使用 NSURLSession 加載主文檔的。當 NSURLSession 接收到 finish 事件時,會將該消息通過進程通信方式傳遞給 WebContent 進程,WebContent 進程再傳遞給 UIProcess 進程,直到被我們的代理方法響應。
    • 因此 didFinishNavigation 在 NSURLSession 的網絡加載結束時就會觸發,但因為跨了兩次進程通信,因此對比網絡層,實際上是有一定的延遲的。與子資源加載和頁面上屏無時間先后關系。

五、Tips

  • 一定要緊密結合三大進程去理解 WebKit 源碼,形成基于進程的知識體系。
  • 可以直接修改源碼驗證猜想,例如在驗證觸發渲染條件時,可以在源碼中禁止網絡層 didfinish 事件執行,并自己構造數據返回,驗證各類上屏觸發條件。

總結

以上是生活随笔為你收集整理的iOS之深入解析WKWebView加载的生命周期与代理方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美人体一区二区三区 | 中文字幕第二页 | 在线观看免费视频a | 97色伦97色伦国产欧美空 | 成年人免费黄色片 | 骚婷婷 | 97视频入口 | 色婷婷成人 | 精品一区二区免费看 | 九九视频免费看 | www日日| 国产成人av网站 | 一二三区免费视频 | 国产不卡在线观看视频 | 欧美三级在线看 | 国产主播福利 | 少妇又白又嫩又色又粗 | 大地资源中文第三页 | 91精品国产综合久久国产大片 | 日本色悠悠 | 精品久久久久久亚洲 | 天天射干 | 最新地址在线观看 | 激情四虎 | 另类国产 | 番号动态图 | 国产天堂第一区 | 自拍亚洲国产 | 毛片在线观看视频 | 国产在线播放一区 | 国产精品视频专区 | aa片在线观看视频在线播放 | 日韩一区二区三区视频在线观看 | 久久亚洲美女 | 毛片福利 | 国产小视频免费 | 欧美激情免费在线观看 | 热热热av| 热99视频| 男女午夜激情 | 免费在线观看www | 国产区在线 | 五月婷婷综合激情 | 欧美精品日韩少妇 | 夜夜看 | 国产片黄色 | 欧美老熟妇又粗又大 | 国产亚洲自拍一区 | 国产精品美女久久久久图片 | 在线亚洲人成电影网站色www | 国产丝袜自拍 | 台湾150部性三级 | 中文在线www | 国产三级av片| 少妇肥臀大白屁股高清 | 国产成人av免费看 | 黄色av片三级三级三级免费看 | exo妈妈mv在线播放免费 | 成人在线免费高清视频 | 国产亚洲制服欧洲高清一区 | 韩国av一区二区 | babes性欧美69| av日韩在线播放 | 欧美一级久久久 | 日韩电影一区二区在线观看 | 三级精品在线观看 | 免费观看nba乐趣影院 | 操操操操操操操操操 | 国产精选自拍 | 久久久久久无码精品人妻一区二区 | 天天看天天操 | 日韩精品久久久久久久的张开腿让 | 久草手机在线观看 | 亚洲日本韩国在线 | 国产视频一区二区在线观看 | 99国产精品免费 | 又黄又爽无遮挡 | 亚洲再线 | 亚洲AV无码乱码国产精品色欲 | 色图社区 | 亲女禁h啪啪宫交 | 国产福利一区在线 | 99成人在线观看 | 在线视频 中文字幕 | 成人爽a毛片一区二区 | 亚洲国产精品国自产拍av | 尼姑福利影院 | 日韩精品乱码久久久久久 | 夜夜骚网站| 大尺度在线观看 | 欧美日本韩国一区二区 | 欧美精品性生活 | 毛片免 | 国产一卡二卡三卡四卡 | 毛片av在线| 黄色草逼视频 | 69精品久久 | 免费在线色 | 国产一区二区三区18 |