「面試常問」從輸入 URL 到顯示發生了什麼( 99 分答案)


前言

讀了李兵老師的 瀏覽器的工作原理與實踐,讓我對瀏覽器的工作原理有了更加深刻的理解,尤其是從用戶輸入 URL 到頁面顯示這一過程發生的事情,以往看的文章都是點到爲止,而他卻說得面面俱到非常詳細,遂我把內容總結了一下分享給大家,值得你花個 5 分鐘閱讀一下。

用戶輸入階段

  1. 合成 URL:用戶輸入 URL,瀏覽器會根據用戶輸入的信息判斷是搜索還是網址,如果是搜索內容,就將搜索內容 + 默認搜索引擎合成新的 URL;如果用戶輸入的內容符合 URL 規則,瀏覽器就會根據 URL 協議,在這段內容上加上協議合成合法的 URL
  2. 加載:用戶輸入完內容,按下回車鍵,瀏覽器導航欄顯示 loading 狀態,但是頁面還是呈現前一個頁面,這是因爲新頁面的響應數據還沒有獲得;

發起URL請求階段

  1. 構建請求:瀏覽器進程首先會構建請求行信息,然後通過進程間通信( IPC)將 URL 請求發送給網絡進程;
  2. 查找緩存:網絡進程獲取到 URL,先去本地緩存中查找是否有緩存資源,如果有則攔截請求,直接將緩存資源返回給瀏覽器進程;否則,進入網絡請求階段;
  3. DNS 解析:網絡進程請求首先會從 DNS 數據緩存服務中查找是否緩存過當前域名信息,有則直接返回;否則,會進行 DNS 解析返回域名對應的 IP 和端口號,如果沒有指定端口號, http 默認 80 端口, https 默認 443。如果是 https 請求,還需要建立 TLS 連接;
  4. 等待 TCP 隊列: Chrome 有個機制,同一個域名同時最多隻能建立 6 個 TCP 連接,如果在同一個域名下同時有 10 個請求發生,那麼其中 4 個請求會進入排隊等待狀態,直至進行中的請求完成。如果當前請求數量少於6個,會直接建立 TCP 連接;
  5. 建立 TCP 連接: TCP 三次握手與服務器建立連接,然後進行數據的傳輸,最後;
  6. 發送 HTTP 請求:瀏覽器首先會向服務器發送請求行,它包含了請求方法、請求 URIHTTP 協議的版本;另外還會發送請求頭,告訴服務器一些瀏覽器的相關信息,比如瀏覽器內核,請求域名、 Cookie 等;如果需要傳遞參數,則還需要發送請求體;
  7. 服務器處理請求:服務器首先返回響應行,包括協議版本和狀態碼,比如狀態碼 200 表示繼續處理該請求;(如果是 301,則表示重定向,將會在響應頭的 Locaiton 字段中加上重定向的地址信息,接下來瀏覽器獲取這個地址,將會重新導航。)服務器也會向瀏覽器發送響應頭,包含了一些信息,比如服務器生成返回數據的時間、返回的數據類型( JSONHTML、流媒體等類型),以及服務器要在客戶端保存的 Cookie 等;繼續發送響應體的數據;
  8. 斷開 TCP 連接:數據傳輸完成,正常情況下 TCP 將四次揮手斷開連接。但是如果瀏覽器或者服務器在HTTP頭部加上 Connection: keep-aliveTCP 就會一直保持連接。保持 TCP 連接可以省下下次需要建立連接的時間,提示資源加載速度;

準備渲染進程階段

  1. 網絡進程將獲取到的數據包進行解析,根據響應頭中的 Content-type 來判斷響應數據的類型,如果是字節流類型,就將該請求交給下載管理器,該導航流程結束,不再進行;如果是 text/html 類型,就通知瀏覽器進程獲取到的是 HTML,應該準備渲染進程了;
  2. 正常情況下每個瀏覽器的 tab 會對應一個渲染進程,但如果從一個頁面打開了另一個新頁面,而新頁面和當前頁面屬於同一站點的話,那麼新頁面會複用父頁面的渲染進程,否則就會創建一個新的渲染進程;

提交文檔階段

  1. 渲染進程準備好後,瀏覽器會發出 “提交文檔” 的消息給渲染進程,渲染進程收到消息後,會和網絡進程建立傳輸數據的 “管道”,文檔數據傳輸完成後,渲染進程會返回“確認提交”的消息給瀏覽器進程;
  2. 瀏覽器收到 “確認提交” 的消息後,會更新瀏覽器的頁面狀態,包括了安全狀態、地址欄的 URL、前進後退的歷史狀態,並更新 web 頁面,此時的 web 頁面是空白頁;

頁面渲染階段

  1. 文檔一旦提交,渲染進程將開始頁面解析和子資源加載;渲染階段比較複雜,所以將分爲多個子階段,按照渲染的時間順序可以分爲:構建 DOM 樹、樣式計算、佈局階段、分層、繪製、分塊、光柵化和合成;
  2. 構建 DOM 樹: HTML 經過解析後輸出一個以 document 爲頂層節點的樹狀結構的 DOM
  3. 樣式計算:這裏有 3 個步驟:
  • 將 3 個來源( <link> 標籤引入的外部樣式、 <style> 標籤裏定義的樣式、以及元素的 style 屬性上的樣式)的 CSS 轉化成瀏覽器能夠理解的結構 styleSheets
  • 轉換樣式表中的屬性值,使其標準化;比如 font-weight: bold; 會轉成 font-weight: 700;color: blue; 會轉成 color: rgb(0, 0, 255); 等;
  • 依據 CSS 的繼承和層疊規則計算出 DOM 樹中每個節點的具體樣式;
  • 佈局階段: DOM 樹中依然存在許多不可見的元素(比如 head),這些元素對於佈局是絲毫沒用的,所以又會生成一棵只包含可見元素的佈局樹;然後再根據佈局樹的每個節點計算出其具體位置和尺寸大小;
  • 分層:頁面中有很多複雜的效果,如一些複雜的 3D 變換、頁面滾動,或者使用 z-index 做 z 軸排序等,爲了更加方便地實現這些效果,渲染引擎還需要爲特定的節點生成專用的圖層,並生成一棵對應的圖層樹;關於層疊上下文的知識,具體可以參考這裏徹底搞懂CSS層疊上下文、層疊等級、層疊順序、z-index;
  • 繪製:爲每個圖層生成繪製列表,並將其提交到合成線程;
  • 光柵化:通常一個頁面很大,而視口很侷限,所以合成線程會按照視口附近的圖塊來優先生成位圖,並在光柵化線程池中將圖塊轉換成位圖;
  • 合成:一旦所有圖塊都被光柵化,合成線程就會生成一個繪製圖塊的命令 DrawQuad,然後將該命令提交給瀏覽器進程;之後瀏覽器將開始生成顯示頁面。
  • 感謝閱讀

    1. 如果你覺得這篇文章對你有所幫助的話,來個分享、點贊、在看三連吧,讓更多的人看到。

    後記

    以上就是胡哥今天給大家分享的內容,喜歡的小夥伴記得收藏轉發,點擊在看推薦給更多的小夥伴。

    胡哥有話說,專注於大前端技術領域,分享前端系統架構,框架實現原理,最新最高效的技術實踐!



    我就知道你在看!


    本文分享自微信公衆號 - 胡哥有話說(hugeyouhuashuo)。
    如有侵權,請聯繫 [email protected] 刪除。
    本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

    發表評論
    所有評論
    還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
    相關文章