從輸入URL到回車發生了什麼

這是一個經典的面試題:html

瞭解這個問題先看下chrome進程架構圖git



從圖中能夠看出Chrome瀏覽器包括:1個瀏覽器主進程,1個GPU進程,一個網絡進程,多個渲染進程,多個插件進程(能夠沒有)github


接下來看下從輸入URL到頁面展現完成示意圖:web


1.用戶輸入回車

當輸入的協議或主機名不合法時,瀏覽器會將地址欄中輸入的文字傳給默認的搜索引擎,來合成新的帶搜索關鍵字的URL面試

若是判斷輸入內容符合 URL 規則,好比輸入的是 www.baidu.com,那麼地址欄會根據規則,把這段內容加上協議,合成爲完整的 URL www.baidu.comchrome

接着就進入了加載階段瀏覽器

當瀏覽器剛開始加載一個地址以後,標籤頁上的圖標便進入了加載狀態。但此時圖中頁面顯示的依然是以前的頁面內容,由於須要等待提交文檔階段,頁面內容纔會被替換。
緩存

2.URL請求過程

接下來,進入頁面資源請求過程。瀏覽器進程會經過進程間通訊(IPC)把 URL 請求發送至網絡進程,網絡進程接收到 URL 請求後,發起 URL 請求流程
安全

網絡進程會查找本地緩存是否緩存了該資源。若是有緩存資源,那麼直接返回資源給瀏覽器進程;若是在緩存中沒有查找到資源,那麼直接進入網絡請求流程。這請求前的第一步是要進行 DNS 解析,獲取請求域名的服務器 IP 地址
服務器

接下來就是利用 IP 地址和服務器創建 TCP 鏈接。



鏈接創建以後,瀏覽器端會構建請求行、請求頭等信息,並把和該域名相關的 Cookie 等數據附加到請求頭中,而後向服務器發送構建的請求信息。下面的圖打印出服務器收到的信息:


服務器接收到請求信息後,會根據請求信息生成響應數據(包括響應行、響應頭和響應體等信息),併發給網絡進程。等網絡進程接收了響應行和響應頭以後,就開始解析響應頭的內容了。

收到服務器返回信息

服務器返回的響應頭的狀態碼是 200,這是告訴瀏覽器一切正常,能夠繼續往下處理該請求了。

而後瀏覽器會根據 Content-Type 的值來決定如何顯示響應體的內容。

Content-Type:  text/html;charset=utf-8

不一樣 Content-Type 的後續處理流程也大相徑庭。若是 Content-Type 字段的值被瀏覽器判斷爲下載類型,那麼該請求會被提交給瀏覽器的下載管理器,同時該 URL 請求的導航流程就此結束

3. 準備渲染進程

Chrome 會爲每一個頁面分配一個渲染進程,也就是說,每打開一個新頁面就會配套建立一個新的渲染進程(打開同一站點的共用一個渲染進程)

4. 提交文檔

「提交文檔」的消息是由瀏覽器進程發出的,渲染進程接收到「提交文檔」的消息後,會和網絡進程創建傳輸數據的「管道"

等文檔數據傳輸完成以後,渲染進程會返回「確認提交」的消息給瀏覽器進程。

瀏覽器進程在收到「確認提交」的消息後,會更新瀏覽器界面狀態,包括了安全狀態、地址欄的 URL、前進後退的歷史狀態,並更新 Web 頁面。

5.渲染階段

先理解什麼是DOM

 從網絡傳給渲染引擎的 HTML 文件字節流是沒法直接被渲染引擎理解的,因此要將其轉化爲渲染引擎可以理解的內部結構,這個結構就是 DOM。DOM 提供了對 HTML 文檔結構化的表述。

  • 從頁面的視角來看,DOM 是生成頁面的基礎數據結構。
  • 從 JavaScript 腳本視角來看,DOM 提供給 JavaScript 腳本操做的接口,經過這套接口,JavaScript 能夠對 DOM 結構進行訪問,從而改變文檔的結構、樣式和內容。

渲染進程接收到「提交文檔」的消息後,會和網絡進程創建傳輸數據的「管道"

在渲染引擎內部,有一個叫HTML 解析器(HTMLParser)的模塊,它的職責就是負責將 HTML 字節流轉換爲 DOM 結構。

網絡進程接收到響應頭以後,會根據響應頭中的 content-type 字段來判斷文件的類型,好比 content-type 的值是「text/html」,那麼瀏覽器就會判斷這是一個 HTML 類型的文件,而後爲該請求選擇或者建立一個渲染進程。渲染進程準備好以後,網絡進程和渲染進程之間會創建一個共享數據的管道  網絡進程接收到數據後就往這個管道里面放,而渲染進程則從管道的另一端不斷地讀取數據,並同時將讀取的數據「喂」給 HTML 解析器。你能夠把這個管道想象成一個「水管」,網絡進程接收到的字節流像水同樣倒進這個「水管」,而「水管」的另一端是渲染進程的 HTML 解析器,它會動態接收字節流,並將其解析爲 DOM。


樣式計算(Recalculate Style)

樣式計算的目的是爲了計算出 DOM 節點中每一個元素的具體樣式,這個階段大致可分爲三步來完成。

CSS 樣式來源主要有三種:

  • 經過 link 引用的外部 CSS 文件
  • <style>標記內的 CSS
  • 元素的 style 屬性內嵌的 CSS

和 HTML 文件同樣,瀏覽器也是沒法直接理解這些純文本的 CSS 樣式,因此當渲染引擎接收到 CSS 文本時,會執行一個轉換操做,將 CSS 文本轉換爲瀏覽器能夠理解的結構——styleSheets

爲了加深理解,你能夠在 Chrome 控制檯中查看其結構,只須要在控制檯中輸入 document.styleSheets,而後就看結構

3. 計算出 DOM 樹中每一個節點的具體樣式



佈局階段

你可能注意到了 DOM 樹還含有不少不可見的元素,好比 head 標籤,還有使用了 display:none 屬性的元素。因此

在顯示以前,咱們還要額外地構建一棵只包含可見元素佈局樹

分層


由於頁面中有不少複雜的效果,如一些複雜的 3D 變換、頁面滾動,或者使用 z-indexing 作 z 軸排序等,爲了更加方便地實現這些效果,渲染引擎還須要爲特定的節點生成專用的圖層,並生成一棵對應的圖層樹

要想直觀地理解什麼是圖層,你能夠打開 Chrome 的「開發者工具」,選擇「Layers」標籤,就能夠可視化頁面的分層狀況,以下圖所示:





圖層繪製

渲染引擎實現圖層的繪製會把一個圖層的繪製拆分紅不少小的繪製指令而後再把這些指令按照順序組成一個待繪製列表,提交給合成線程

合成線程將圖層分紅圖塊,並在光柵化線程池中將圖塊轉換成位圖。

合成線程發送繪製圖塊命令DrawQuad給瀏覽器進程。

瀏覽器進程根據 DrawQuad 消息生成頁面顯示到顯示器上。

問題:


  • 爲何必定要經過瀏覽器內核請求資源,再將數據轉發給渲染進程而不是直接去請求資源
  • 爲何渲染進程只負責生成圖片,生成圖片還有經過IPC通知瀏覽器內核模塊,交由內核去展現圖片

基於安全考慮:下載一個惡意程序,不去執行他,惡意程序是不會生效的,解析執行這些內容就要當心了,因此渲染進程和操做系統進行了隔離便是安全沙箱,因此渲染進程須要訪問系統資源都是經過瀏覽器內核實現,經過IPC通訊獲取結果!


瀏覽器的加載過程

瀏覽器調試使用

what-happens-when-zh_CN

相關文章
相關標籤/搜索