前言
讀了李兵老師的 瀏覽器的工作原理與實踐,讓我對瀏覽器的工作原理有了更加深刻的理解,尤其是從用戶輸入 URL 到頁面顯示這一過程發生的事情,以往看的文章都是點到爲止,而他卻說得面面俱到非常詳細,遂我把內容總結了一下分享給大家,值得你花個 5 分鐘閱讀一下。
用戶輸入階段
-
合成 URL
:用戶輸入URL
,瀏覽器會根據用戶輸入的信息判斷是搜索還是網址,如果是搜索內容,就將搜索內容 + 默認搜索引擎合成新的URL
;如果用戶輸入的內容符合URL
規則,瀏覽器就會根據URL
協議,在這段內容上加上協議合成合法的URL
; -
加載:用戶輸入完內容,按下回車鍵,瀏覽器導航欄顯示 loading
狀態,但是頁面還是呈現前一個頁面,這是因爲新頁面的響應數據還沒有獲得;
發起URL請求階段
-
構建請求:瀏覽器進程首先會構建請求行信息,然後通過進程間通信( IPC
)將URL
請求發送給網絡進程; -
查找緩存:網絡進程獲取到 URL
,先去本地緩存中查找是否有緩存資源,如果有則攔截請求,直接將緩存資源返回給瀏覽器進程;否則,進入網絡請求階段; -
DNS
解析:網絡進程請求首先會從DNS
數據緩存服務中查找是否緩存過當前域名信息,有則直接返回;否則,會進行DNS
解析返回域名對應的IP
和端口號,如果沒有指定端口號,http
默認 80 端口,https
默認 443。如果是https
請求,還需要建立TLS
連接; -
等待 TCP
隊列:Chrome
有個機制,同一個域名同時最多隻能建立 6 個TCP
連接,如果在同一個域名下同時有 10 個請求發生,那麼其中 4 個請求會進入排隊等待狀態,直至進行中的請求完成。如果當前請求數量少於6個,會直接建立TCP
連接; -
建立 TCP
連接:TCP
三次握手與服務器建立連接,然後進行數據的傳輸,最後; -
發送 HTTP
請求:瀏覽器首先會向服務器發送請求行,它包含了請求方法、請求URI
和HTTP
協議的版本;另外還會發送請求頭,告訴服務器一些瀏覽器的相關信息,比如瀏覽器內核,請求域名、Cookie
等;如果需要傳遞參數,則還需要發送請求體; -
服務器處理請求:服務器首先返回響應行,包括協議版本和狀態碼,比如狀態碼 200 表示繼續處理該請求;(如果是 301,則表示重定向,將會在響應頭的 Locaiton
字段中加上重定向的地址信息,接下來瀏覽器獲取這個地址,將會重新導航。)服務器也會向瀏覽器發送響應頭,包含了一些信息,比如服務器生成返回數據的時間、返回的數據類型(JSON
、HTML
、流媒體等類型),以及服務器要在客戶端保存的Cookie
等;繼續發送響應體的數據; -
斷開 TCP
連接:數據傳輸完成,正常情況下TCP
將四次揮手斷開連接。但是如果瀏覽器或者服務器在HTTP頭部加上Connection: keep-alive
,TCP
就會一直保持連接。保持TCP
連接可以省下下次需要建立連接的時間,提示資源加載速度;
準備渲染進程階段
-
網絡進程將獲取到的數據包進行解析,根據響應頭中的 Content-type
來判斷響應數據的類型,如果是字節流類型,就將該請求交給下載管理器,該導航流程結束,不再進行;如果是text/html
類型,就通知瀏覽器進程獲取到的是HTML
,應該準備渲染進程了; -
正常情況下每個瀏覽器的 tab 會對應一個渲染進程,但如果從一個頁面打開了另一個新頁面,而新頁面和當前頁面屬於同一站點的話,那麼新頁面會複用父頁面的渲染進程,否則就會創建一個新的渲染進程;
提交文檔階段
-
渲染進程準備好後,瀏覽器會發出 “提交文檔” 的消息給渲染進程,渲染進程收到消息後,會和網絡進程建立傳輸數據的 “管道”,文檔數據傳輸完成後,渲染進程會返回“確認提交”的消息給瀏覽器進程; -
瀏覽器收到 “確認提交” 的消息後,會更新瀏覽器的頁面狀態,包括了安全狀態、地址欄的 URL
、前進後退的歷史狀態,並更新web
頁面,此時的web
頁面是空白頁;
頁面渲染階段
-
文檔一旦提交,渲染進程將開始頁面解析和子資源加載;渲染階段比較複雜,所以將分爲多個子階段,按照渲染的時間順序可以分爲:構建 DOM
樹、樣式計算、佈局階段、分層、繪製、分塊、光柵化和合成; -
構建 DOM
樹:HTML
經過解析後輸出一個以document
爲頂層節點的樹狀結構的DOM
; -
樣式計算:這裏有 3 個步驟:
-
將 3 個來源( <link>
標籤引入的外部樣式、<style>
標籤裏定義的樣式、以及元素的style
屬性上的樣式)的CSS
轉化成瀏覽器能夠理解的結構styleSheets
; -
轉換樣式表中的屬性值,使其標準化;比如 font-weight: bold;
會轉成font-weight: 700;
、color: blue;
會轉成color: rgb(0, 0, 255);
等; -
依據 CSS
的繼承和層疊規則計算出DOM
樹中每個節點的具體樣式;
DOM
樹中依然存在許多不可見的元素(比如
head
),這些元素對於佈局是絲毫沒用的,所以又會生成一棵只包含可見元素的佈局樹;然後再根據佈局樹的每個節點計算出其具體位置和尺寸大小;
z-index
做 z 軸排序等,爲了更加方便地實現這些效果,渲染引擎還需要爲特定的節點生成專用的圖層,並生成一棵對應的圖層樹;關於層疊上下文的知識,具體可以參考這裏徹底搞懂CSS層疊上下文、層疊等級、層疊順序、z-index;
DrawQuad
,然後將該命令提交給瀏覽器進程;之後瀏覽器將開始生成顯示頁面。
感謝閱讀
後記
以上就是胡哥今天給大家分享的內容,喜歡的小夥伴記得收藏
、轉發
,點擊在看
推薦給更多的小夥伴。
胡哥有話說,專注於大前端技術領域,分享前端系統架構,框架實現原理,最新最高效的技術實踐!
本文分享自微信公衆號 - 胡哥有話說(hugeyouhuashuo)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。