簡單談談瀏覽器從輸入URL到頁面渲染的過程

簡單談談瀏覽器從輸入URL到頁面渲染的過程

這也是一個經典的面試題,不管前端仍是後端均可能都會遇到,知識點相對來講也比較多,考察得比較全面的。最近也看了不少瀏覽器相關的文章,結合起來,在這裏簡單梳理總結下。同時,感謝瀏覽器這個偉大的發明。html

知識點羅列

下面是我簡單粗糙畫的一張流程圖:前端

url-browser.png

過程分爲下方几個流程:git

  • DNS解析:把域名解析成IP地址
  • TCP 創建鏈接:TCP三次握手
  • 發送HTTP請求
  • 服務器處理並響應報文
  • 瀏覽器解析並渲染頁面
  • 斷開鏈接:TCP 結束鏈接

相關知識點:github

URLweb

DNS解析、IP地址面試

TCP創建鏈接、三次握手後端

服務器處理、HTTP請求、狀態碼瀏覽器

瀏覽器渲染bash

TCP鏈接結束服務器

1、什麼是URL?

URL(Uniform Resource Locator),統一資源定位符,用於定位互聯網上資源,俗稱網址。

通常遵照下面的語法規則:

scheme://host.domain:port/path/filename

各部分解釋以下:

  • scheme - 定義因特網服務的類型。常見的協議有 http、https、ftp、file,其中最多見的類型是 http,而 https 則是進行加密的網絡傳輸。
  • host - 定義域主機(http 的默認主機是 www)
  • domain - 定義因特網域名,好比 baodu.com
  • port - 定義主機上的端口號(http 的默認端口號是 80)
  • path - 定義服務器上的路徑(若是省略,則文檔必須位於網站的根目錄中)
  • filename - 定義文檔/資源的名稱

2、域名解析(DNS)

爲何須要域名解析? 瀏覽器並不能直接經過域名找到對應的服務器,而是要經過 IP 地址。固然也能夠直接IP地址去訪問,可是以人類的記憶習慣去記住各個網站的IP地址...那,我只能祝你幸福。

先說下IP地址: IP 地址是一個 32 位的二進制數,好比 127.0.0.1 爲本機 IP。它的做用就是便於記憶和溝通的一組服務器的地址。域名就至關於 IP 地址的別名。 舉個方便理解例子:好比一個經度:113.35 緯度:23.12 的地點,這樣很是不方便記憶,可是這個地方有個地名叫廣州天河,那個這就很符合人類的認知了。例子裏面的經緯度就至關於IP地址,廣州天河就至關於域名。

什麼是域名解析 DNS 協議提供經過域名查找 IP 地址,或逆向從 IP 地址反查域名的服務。DNS 是一個網絡服務器,咱們的域名解析簡單來講就是在 DNS 上記錄一條信息記錄。

例如 xiaoyexiang.com  120.77.215.71(服務器外網IP地址)80(服務器端口號)
複製代碼

3、TCP 三次握手

在客戶端發送數據以前會發起 TCP 三次握手用以同步客戶端和服務端的序列號和確認號,並交換 TCP 窗口大小信息。

網上也有不少方便易解的過程,這裏我直接引用:

  1. TCP 三次握手的過程以下:
    • 客戶端發送一個帶 SYN=1,Seq=X 的數據包到服務器端口(第一次握手,由瀏覽器發起,告訴服務器我要發送請求了)
    • 服務器發回一個帶 SYN=1, ACK=X+1, Seq=Y 的響應包以示傳達確認信息(第二次握手,由服務器發起,告訴瀏覽器我準備接受了,你趕忙發送吧)
    • 客戶端再回傳一個帶 ACK=Y+1, Seq=Z 的數據包,表明「握手結束」(第三次握手,由瀏覽器發送,告訴服務器,我立刻就發了,準備接受吧)
  2. 爲啥須要三次握手? 謝希仁著《計算機網絡》中講「三次握手」的目的是**「爲了防止已失效的鏈接請求報文段忽然又傳送到了服務端,於是產生錯誤」**。

4、向服務器發送HTTP請求

創建TCP鏈接後,開始向Web服務器發送HTTP請求報文。

  • 請求方法包含 8 種:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE。
  • URL 即請求地址,由 <協議>://<主機>:<端口>/<路徑>?<參數> 組成
  • 協議版本即 http 版本號
POST  /chapter17/user.html HTTP/1.1

// 以上代碼中「POST」表明請求方法,「/chapter17/user.html」表示 URL,「HTTP/1.1」表明協議和協議的版本。如今比較流行的是 Http1.1 版本
複製代碼

一個典型的 http request header 通常須要包括請求的方法,例如 GET 或者 POST 等,不經常使用的還有 PUT 和 DELETE 、HEAD、OPTION以及 TRACE 方法,通常項目中,瀏覽器只會發起 GET 或者 POST 請求。

服務器處理請求並返回 HTTP 報文

此處注意: 這裏可能會發生用戶輸入的爲「baidu.com/」而非「https:/…參見文章

服務器接受到請求後,對相應的請求做出相應的處理,處理完成後並做出相應的http 響應報文

** 響應行包含:協議版本,狀態碼,狀態碼描述 **

狀態碼規則以下:

  • 1xx:指示信息--表示請求已接收,繼續處理。
  • 2xx:成功--表示請求已被成功接收、理解、接受。
  • 3xx:重定向--要完成請求必須進行更進一步的操做。
  • 4xx:客戶端錯誤--請求有語法錯誤或請求沒法實現。
  • 5xx:服務器端錯誤--服務器未能實現合法的請求。

此處對於服務器處理,我的表示瞭解很少

6、瀏覽器解析渲染頁面

不作過多解釋,搬我以爲網上比較簡單易懂的

瀏覽器拿到響應文本 HTML 後,接下來介紹下瀏覽器渲染機制

render.png

瀏覽器解析渲染頁面分爲一下五個步驟:

  • 根據 HTML 解析出 DOM 樹
  • 根據 CSS 解析生成 CSS 規則樹
  • 結合 DOM 樹和 CSS 規則樹,生成渲染樹
  • 根據渲染樹計算每個節點的信息
  • 根據計算好的信息繪製頁面
  1. 根據 HTML 解析 DOM 樹
    • 根據 HTML 的內容,將標籤按照結構解析成爲 DOM 樹,DOM 樹解析的過程是一個深度優先遍歷。即先構建當前節點的全部子節點,再構建下一個兄弟節點。
    • 在讀取 HTML 文檔,構建 DOM 樹的過程當中,若遇到 script 標籤,則 DOM 樹的構建會暫停,直至腳本執行完畢。
  2. 根據 CSS 解析生成 CSS 規則樹
    • 解析 CSS 規則樹時 js 執行將暫停,直至 CSS 規則樹就緒。
    • 瀏覽器在 CSS 規則樹生成以前不會進行渲染。
  3. 結合 DOM 樹和 CSS 規則樹,生成渲染樹
    • DOM 樹和 CSS 規則樹所有準備好了之後,瀏覽器纔會開始構建渲染樹。
    • 精簡 CSS 並能夠加快 CSS 規則樹的構建,從而加快頁面相應速度。
  4. 根據渲染樹計算每個節點的信息(佈局)
    • 佈局:經過渲染樹中渲染對象的信息,計算出每個渲染對象的位置和尺寸
    • 迴流:在佈局完成後,發現了某個部分發生了變化影響了佈局,那就須要倒回去從新渲染。
  5. 根據計算好的信息繪製頁面
    • 繪製階段,系統會遍歷呈現樹,並調用呈現器的「paint」方法,將呈現器的內容顯示在屏幕上。
    • 重繪:某個元素的背景顏色,文字顏色等,不影響元素周圍或內部佈局的屬性,將只會引發瀏覽器的重繪。
    • 迴流:某個元素的尺寸發生了變化,則需從新計算渲染樹,從新渲染。

7、斷開鏈接

當數據傳送完畢,須要斷開 tcp 鏈接,此時發起 tcp 四次揮手。

  • 發起方向被動方發送報文,Fin、Ack、Seq,表示已經沒有數據傳輸了。並進入 FIN_WAIT_1 狀態。(第一次揮手:由瀏覽器發起的,發送給服務器,我請求報文發送完了,你準備關閉吧)
  • 被動方發送報文,Ack、Seq,表示贊成關閉請求。此時主機發起方進入 FIN_WAIT_2 狀態。(第二次揮手:由服務器發起的,告訴瀏覽器,我請求報文接受完了,我準備關閉了,你也準備吧)
  • 被動方向發起方發送報文段,Fin、Ack、Seq,請求關閉鏈接。並進入 LAST_ACK 狀態。(第三次揮手:由服務器發起,告訴瀏覽器,我響應報文發送完了,你準備關閉吧)
  • 發起方向被動方發送報文段,Ack、Seq。而後進入等待 TIME_WAIT 狀態。被動方收到發起方的報文段之後關閉鏈接。發起方等待必定時間未收到回覆,則正常關閉。(第四次揮手:由瀏覽器發起,告訴服務器,我響應報文接受完了,我準備關閉了,你也準備吧)

8、瀏覽器發生異步請求

在web2.0時代,即便在頁面渲染後客戶端仍是持續與服務器端通訊,這個模式被稱爲AJAX,是「Asynchronous JavaScript And XML」的縮寫。

JS的解析是由瀏覽器中的JS解析引擎完成的。JS是單線程運行,也就是說,在同一個時間內只能作一件事,全部的任務都須要排隊,前一個任務結束,後一個任務才能開始。可是又存在某些任務比較耗時,如IO讀寫等,因此須要一種機制能夠先執行排在後面的任務,這就是:同步任務(synchronous)和異步任務(asynchronous)。JS的執行機制就能夠看作是一個主線程加上一個任務隊列(task queue)。同步任務就是放在主線程上執行的任務,異步任務是放在任務隊列中的任務。全部的同步任務在主線程上執行,造成一個執行棧;異步任務有了運行結果就會在任務隊列中放置一個事件;腳本運行時先依次運行執行棧,而後會從任務隊列裏提取事件,運行任務隊列中的任務,這個過程是不斷重複的,因此又叫作事件循環(Event loop)。

瀏覽器在解析過程當中,若是遇到請求外部資源時,請求過程是異步的,並不會影響HTML文檔進行加載,可是當文檔加載過程當中遇到JS文件,HTML文檔會掛起渲染過程,不只要等到文檔中JS文件加載完畢還要等待解析執行完畢,纔會繼續HTML的渲染過程。緣由是由於JS有可能修改DOM結構,這就意味着JS執行完成前,後續全部資源的下載是沒有必要的,這就是JS阻塞後續資源下載的根本緣由。CSS文件的加載不影響JS文件的加載,可是卻影響JS文件的執行。JS代碼執行前瀏覽器必須保證CSS文件已經下載並加載完畢。

內容參考網上文章整理,僅限我的學習使用:

www.beiliangshizi.com/441/

github.com/ljianshu/Bl…

相關文章
相關標籤/搜索