從一道面試題來了解瀏覽器渲染過程

前言

做爲前端工程師,幾乎是天天都要與各類瀏覽器打交道。html

理解瀏覽器是如何工做的,對咱們作業務的技術選型、架構設計等都有很是重要的做用,可讓咱們準確的評估web開的項目的可行性,站在更高維度審視頁面,以及在快節奏的技術迭代中把握住問題的本質。前端

那麼咱們就從一道面試題在瀏覽器裏面,從輸入URL到展現頁面,這過程發生了什麼?來解開瀏覽器神祕的面紗web

在瞭解流程以前咱們先來看一下瀏覽器的架構:面試

瀏覽器架構

當代現有的瀏覽器主要由:chrome

  • 用戶界面(The user interface)、
  • 瀏覽器引擎(The browser engine)、
  • 呈現引擎(The rendering engine)、
  • 網絡(Networking)、
  • JavasScript 解釋器(JavaScript interpreter)、
  • 用戶界面後端(UI backend)、
  • 數據存儲組成(Data storage)。

image-20191010144108447

  1. 用戶界面 - 包括地址欄、前進/後退按鈕、書籤菜單等。除了瀏覽器主窗口顯示的您請求的頁面外,其餘顯示的各個部分都屬於用戶界面。
  2. 瀏覽器引擎 - 在用戶界面和呈現引擎之間傳送指令。
  3. 渲染引擎 - 負責顯示請求的內容。若是請求的內容是 HTML,它就負責解析 HTML 和 CSS 內容,並將解析後的內容顯示在屏幕上。
  4. 網絡 - 用於網絡調用,好比 HTTP 請求。其接口與平臺無關,併爲全部平臺提供底層實現。
  5. 用戶界面後端 - 用於繪製基本的窗口小部件,好比組合框和窗口。其公開了與平臺無關的通用接口,而在底層使用操做系統的用戶界面方法。
  6. JavaScript 解釋器。用於解析和執行 JavaScript 代碼。
  7. 數據存儲。這是持久層。瀏覽器須要在硬盤上保存各類數據,例如 Cookie。新的 HTML 規範 (HTML5) 定義了「網絡數據庫」,這是一個完整(可是輕便)的瀏覽器內數據庫。

那麼在瞭解完瀏覽器的架構以後,再來看一下URL的解析過程數據庫

瀏覽器解析過程

  • DNS解析
  • TCP鏈接
  • 發送HTTP請求
  • 服務器處理請求並返回HTTP報文
  • 瀏覽器解析渲染過程

DNS解析解析過程

當發送一個url請求時,無論這個url是web頁面的url仍是web頁面上的每一個資源的url,瀏覽器都會開啓一個線程處理該請求,同時在遠程DNS服務器上啓動一個DNS查詢,這能使瀏覽器得到請求對應的IP地址後端

  • 本地DNS服務器拿到請求後會首先查詢它的緩存記錄,若是緩存有這條記錄的話就直接返回。這個時候拿到的ip地址,會被標記爲非權威服務器的應答。
  • 若是沒有,本地DNS服務器還要向DNS根服務器進行查詢(會從配置文件裏面讀取13個根域名服務器的地址,而後向其中一臺發起請求。)
  • 根DNS服務器拿到這個請求後,告訴本地DNS服務器,你能夠到域服務器上去繼續查詢,並給出域服務器的地址。這種過程是迭代的過程,(好比知道他是com.這個頂級域名下的,因此就會返回com域中的NS記錄。)
  • 而後本地DNS服務器繼續向域服務器發出請求,在這個例子中,請求的對象是.com域服務器。.com域服務器收到請求以後,也不會直接返回域名和IP地址的對應關係,而是告訴本地DNS服務器,你的域名的解析服務器的地址,(好比,com域的服務器發現你這請求是baidu.com這個域的,一查發現了這個域的NS,那我就返回給你,你再去查。)
  • 最後,本地DNS服務器向域名的解析服務器發出請求,這時就能收到一個域名和IP地址對應關係,本地DNS服務器把IP地址返回給用戶電腦,並把這個對應關係保存在緩存中,以備下次別的用戶查詢時,能夠直接返回結果,加快網絡訪問。(好比,向baidu.com這個域的權威服務器發起請求,baidu.com收到以後,查了下有www的這臺主機,就把這個IP返回給你了,而後ISPDNS拿到了以後,將其返回給了客戶端,而且把這個保存在高速緩存中。)

網址的解析是一個從右向左的過程: com -> google.com -> www.google.com;瀏覽器

事實上,真正的網址是www.google.com.,這個.對應的就是根域名服務器,默認狀況下全部的網址的最後一位都是.,既然是默認狀況下,爲了方便用戶,一般都會省略,瀏覽器在請求DNS的時候會自動加上,全部網址真正的解析過程爲: . -> .com -> google.com. -> www.google.com.。緩存

DNS域名類別

名稱 說明 示例
根域 DNS域名使用時,規定由尾部局點(.)來指定名稱位於根或者更高級的域層次結構 單個句點(.)或者句點用於末尾的名稱
頂級域 用於指示某個國家/地區或者組織使用的名稱類 .com
第二層域 我的或者組織在Internet上使用的註冊名稱 baidu.com
子域 已註冊的二級域名派生的域名,同屬的講就是網站名 www.baidu.com
主機名 一般狀況下,DNS域名的最左側的標籤標示網絡上的特定計算機,如h1 h1.www.baidu.com

TCP創建鏈接

在http消息發送前,須要創建客戶端與服務器的TCP連接,也就是進行所謂的三次握手
TCP是因特網中的傳輸層協議,使用三次握手協議)創建鏈接。當主動方發出SYN鏈接請求後,等待對方回答SYN+ACK,並最終對對方的 SYN 執行 ACK 確認。這種創建鏈接的方法能夠防止產生錯誤的鏈接,TCP使用的流量控制協議是可變大小的滑動窗口協議。服務器

TCP三次握手的過程以下:

  1. 客戶端發送SYN(SEQ=x)報文給服務器端,進入SYN_SEND狀態。
  2. 服務器端收到SYN報文,迴應一個SYN (SEQ=y)ACK(ACK=x+1)報文,進入SYN_RECV狀態。
  3. 客戶端收到服務器端的SYN報文,迴應一個ACK(ACK=y+1)報文,進入Established狀態。

三次握手完成,TCP客戶端和服務器端成功地創建鏈接,能夠開始傳輸數據了。

發起HTTP請求

進過TCP3次握手以後,瀏覽器發起了http的請求;

chrome瀏覽器查看報文首部信息:

服務器請求處理

如今請求只是成功達到了服務器,接下來服務器須要響應瀏覽器的請求。
服務器端收到請求後的由web服務器(準確說應該是http服務器)處理請求,諸如Apache、Ngnix、IIS等。web服務器解析用戶請求,知道了須要調度哪些資源文件,再經過相應的這些資源文件處理用戶請求和參數,並調用數據庫信息,最後將結果經過web服務器返回給瀏覽器客戶端。

在HTTP裏,有請求就會有響應,哪怕是錯誤信息。這裏咱們一樣看下響應報文的組成結構:

在響應結果中都會有個一個HTTP狀態碼,好比咱們熟知的200、30一、40四、500等。經過這個狀態碼咱們能夠知道服務器端的處理是否正常,並能瞭解具體的錯誤。
狀態碼由3位數字和緣由短語組成。根據首位數字,狀態碼能夠分爲五類:

狀態碼 類別 說明
1-- 信息性狀態碼 接收的請求正在處理
2-- 成功狀態碼 請求正常處理完畢
3-- 重定向狀態碼 須要進行附加操做已完成請求
4-- 客戶端錯誤狀態碼 服務器沒法處理請求
5-- 服務器錯誤狀態碼 服務器處理請求出錯

從上面的URL請求咱們能看到headers裏面的Accept是text/html類型,這部分頭部說明了瀏覽器將響應內容做爲HTML渲染,而不是做爲文件下載。瀏覽器將使用頭部決定如何解釋響應結果,固然也會考慮其餘因素,好比URL的擴展狀況。

瀏覽器渲染解析

當瀏覽器得到一個html文件時,會「自上而下」加載,並在加載過程當中進行解析渲染。
解析:

  1. 瀏覽器會將HTML解析成一個DOM樹,DOM 樹的構建過程是一個深度遍歷過程:當前節點的全部子節點都構建好後纔會去構建當前節點的下一個兄弟節點。
  2. 將CSS解析成 CSS Rule Tree 。
  3. 根據DOM樹和CSSOM來構造 Rendering Tree。注意:Rendering Tree 渲染樹並不等同於 DOM 樹,由於一些像 Header 或 display:none 的東西就不必放在渲染樹中了。
相關文章
相關標籤/搜索