(詳解)從瀏覽器輸入 URL 到頁面展現過程發生了什麼?

引言

對於面試常問的從瀏覽器輸入 URL 到頁面展現過程發生了什麼?,我想你們都或多或少能說出一二。可是,其實這個問題頗有深度,而你是否回答的有深度,在很大程度上會影響到面試官對你的印象。javascript

而且,網上各類資料都是淺嘗輒止地講解這個過程,常常會出現今天看到這個版本,明天看到另外一個版本地狀況。因此,此次咱們就來深刻淺出一下這整個過程~css

1、Chrome 多進程架構

首先,在開始講解整個過程前,咱們須要認識一下 Chrome 多進程架構。由於,從瀏覽器輸入 URL 到頁面渲染的整個過程都是由 Chrome 架構中的各個進程之間的配合完成。html

Chrome 的多進程架構:java

  • 瀏覽器進程,它負責用戶界面(地址欄、菜單等等)、子進程的管理(例如,進程間通訊和數據傳遞)、存儲等等
  • 渲染進程,它負責將接收到的 HTML 文檔和 JavaScript 等轉化爲用戶界面
  • 網絡進程,它負責網絡資源的請求,例如 HTTP請求、 WebSocket 模塊
  • GPU(圖形處理器)進程,它負責對 UI 界面的展現
  • 插件進程,它負責對插件的管理

2、過程詳解

2.1 解析輸入

發生這個過程的前提,用戶在地址欄中輸入了 URL,而地址欄會根據用戶輸入,作出以下判斷:node

  • 輸入的是非 URL 結構的字符串,則會用瀏覽器默認的搜索引擎搜索該字符串
  • 輸入的是 URL 結構字符串,則會構建完整的 URL 結構,瀏覽器進程會將完整的 URL 經過進程間通訊,即 IPC,發送給網絡進程

2.2 請求過程

在網絡進程接收到 URL 後,並非立刻對指定 URL 進行請求。首先,咱們須要進行 DNS 解析域名獲得對應的 IP,而後經過 ARP 解析 IP 獲得對應的 MACMedia Access Control Address)地址。web

域名是咱們取代記憶複雜的 IP 的一種解決方案,而 IP 地址纔是目標在網絡中所被分配的節點。MAC 地址是對應目標網卡所在的固定地址。面試

1. DNS 解析瀏覽器

DNS 解析域名的過程分爲如下幾個步驟:緩存

  • 詢問瀏覽器 DNS 緩存
  • 詢問本地操做系統 DNS 緩存(即查找本地 host 文件)
  • 詢問 ISPInternet Service Provider)互聯網服務提供商(例如電信、移動)的 DNS 服務器
  • 詢問根服務器,這個過程能夠進行遞歸和迭代兩種查找的方式,二者都是先詢問頂級域名服務器查找

2. 通訊過程安全

首先,創建 TCP 鏈接,即三次握手過程

  • 客戶端發送標有 SYN 的數據包,表示我將要發送請求。
  • 服務端發送標有 SYN/ACK 的數據包,表示我已經收到通知,告知客戶端發送請求。
  • 客戶端發送標有 ACK 的數據包,表示我要開始發送請求,準備被接受。

而後,利用 TCP 通道進行數據傳輸

  • 服務端接收到數據包,併發送確認數據包已收到的消息到客戶端,不斷重複這個過程
  • 客戶端在發送一個數據包後,未接收到服務端的肯定消息,則從新發送該數據包,即 TCP重發機制
  • 當接收完全部的數據包後,接收端會按照 TCP 頭中的須要進行 排序,造成完整的數據

最後,斷開 TCP 鏈接,即四次握手過程

  • 客戶端發送請求,申請斷開鏈接,進入等待階段,此時不會發送數據,可是會繼續接收數據。
  • 服務端接收請求後,告知客戶端已明白,此時服務端進入等待狀態,不會再接收數據,可是會繼續發送數據。
  • 客戶端收到後,進入下一階段等待。
  • 服務端發送完剩餘的數據後,告知客戶端能夠斷開鏈接,此時服務端不會發送和接收數據。
  • 客戶端收到後,告知服務端我開始斷開鏈接。
  • 服務端收到後,開始斷開鏈接。

而這整個過程的客戶端則是網絡進程。而且,在數據傳輸的過程還可能會發生的重定向的狀況,即當網絡進程接收到狀態碼爲 3xx 的響應報文,則會根據響應報文首部字段中的 Location 字段的值進行重定向,即會從新發起請求

3. 數據處理

當網絡進程接收到的響應報文狀態碼,進行相應的操做。例如狀態碼爲 200 OK 時,會解析響應報文中的 Content-Type 首部字段,例如咱們這個過程 Content-Type 會出現 application/javascripttext/csstext/html,即對應 Javascript 文件、CSS 文件、HTML 文件。

詳細的 MIME 類型講解能夠看 MDN

2.3 建立渲染進程

當前須要渲染 HTML 時,則須要建立渲染進程,用於後期渲染 HTML。而對於渲染進程,若是是同一站點是能夠共享一個渲染進程,例如 a.abc.comc.abc.com 能夠共享一個渲染渲染進程。不然,須要從新建立渲染進程

須要注意的是,同站指的是頂級域名二級域名相等

2.4 開始渲染

在建立完渲染進程後,網絡進程會將接收到的 HTML、JavaScript 等數據傳遞給渲染進程。而在渲染進程接收完數據後,此時用戶界面上會發生這幾件事:

  • 更新地址欄的安全狀態
  • 更新地址欄的 URL
  • 前進後退此時 enable,顯示正在加載狀態
  • 更新網頁

2.5 渲染過程

你們都知道頁面渲染的過程也是面試中單獨會考的點,而且時常會由這個點延申出另外一個問題,即如何避免迴流和重繪。

渲染過程,是整個從瀏覽器輸入 URL 到頁面渲染過程的最後一步。而頁面渲染的過程能夠分爲 9 個步驟:

  • 解析 HTML 生成 DOM
  • 解析 CSS 生成 CSSOM
  • 加載或執行 JavaScript
  • 生成渲染樹( Render Tree
  • 佈局
  • 分層
  • 生成繪製列表
  • 光柵化
  • 顯示

2.5.1 構建 DOM 樹

因爲網絡進程傳輸給渲染進程的是 HTML 字符串,因此,渲染進程須要將 HTML 字符串轉化成 DOM 樹。例如:

須要注意的是這個 DOM 樹不一樣於 Chrome-devtoolElement 選項卡的 DOM 樹,它是存在內存中的,用於提供 JavaScriptDOM 的操做。

2.5.2 構建 CSSOM

構建 CSSOM 的過程,即經過解析 CSS 文件、style 標籤、行內 style 等,生成 CSSOM。而這個過程會作這幾件事:

  • 規範 CSS,即將 color: blue 轉化成 color: rgb() 形式,能夠理解成相似 ES6ES5 的過程
  • 計算元素樣式,例如 CSS 樣式會繼承父級的樣式,如 font-sizecolor 之類的。

CSS Object Model 是一組容許用 JavaScript 操縱 CSSAPI。詳細 API 講解能夠看 MDN

2.5.3 加載 JavaScript

一般狀況下,在構建 DOM 樹或 CSSOM 的同時,若是也要加載 JavaScript,則會形成前者的構建的暫停。固然,咱們能夠經過 defersync 來實現異步加載 JavaScript。雖然 defersync 均可以實現異步加載 JavaScript,可是前者是在加載後,等待 CSSOMDOM 樹構建完後才執行 JavaScript,然後者是在異步加載完立刻執行,即便用 sync 的方式仍然會形成阻塞。

JavaScript 執行的過程,即編譯和運行 JavaScript 的過程。因爲 JavaScript解釋型的語言。因此這個過程會是這樣的:

  • 針對每句代碼進行分行處理,即 Token
  • 根據 Token,生成 ASTAbstract Sytanx Tree) 抽象語法樹和建立上下文
  • 解釋器解析和執行 AST,生成字節碼。
  • 編譯器針對須要反覆執行的代碼,生成對應的機器碼,提升運行效率

2.5.4 生成渲染樹(Render Tree)

在有了 DOM 樹和 CSSOM 以後,須要將二者結合生成渲染樹 Render Tree,而且這個過程會去除掉那些 display: node 的節點。此時,渲染樹就具有元素和元素的樣式信息。

2.5.5 佈局

根據 Render Tree 渲染樹,對樹中每一個節點進行計算,肯定每一個節點在頁面中的寬度、高度和位置。

須要注意的是,第一次肯定節點的大小和位置的過程稱爲佈局,而第二次才被稱爲迴流

2.5.6 分層

因爲層疊上下文的存在,渲染引擎會爲具有層疊上下文的元素建立對應的圖層,而諸多圖層的疊加就造成了咱們看到的一些頁面效果。例如,一些 3D 的效果、動畫就是基於圖層而造成的。

值得一提的是,對於內容溢出存在滾輪的狀況也會進行分層

2.5.7 生成繪製列表

對於存在圖層的頁面部分,須要進行有序的繪製,而對於這個過程,渲染引擎會將一個個圖層的繪製拆分紅繪製指令,並按照圖層繪製順序造成一個繪製列表。

2.5.8 光柵化

有了繪製列表後,渲染引擎中的合成線程會根據當前視口的大小將圖層進行分塊處理,而後合成線程會對視口附近的圖塊生成位圖,即光柵化。而渲染進程也維護了一個柵格化的線程池,專門用於將圖塊轉爲位圖。

光柵化的過程一般會使用 GPU 加速,例如使用 wil-changeopacity,就會經過 GPU 加速顯示

2.5.9 顯示

當全部的圖塊都通過柵格化處理後,渲染引擎中的合成線程會生成繪製圖塊的指令,提交給瀏覽器進程。而後瀏覽器進程將頁面繪製到內存中。最後將內存繪製結果顯示在用戶界面上。

而這個整個從生成繪製列表、光柵化、顯示的過程,就是咱們常說的重繪的過程

結語

整個瀏覽器輸入 URL 到頁面渲染的過程涉及到的知識點很是廣,如 Chrome 多進程的架構、HTTP 通訊過程、瀏覽器解析 JavaScript 過程、瀏覽器繪製頁面過程以及一些計算機的基礎知識等等,而且,這整個過程的分析其實和 Chrome-devtools 密切相關,因此很好的使用 Chrome-devtools 是很是重要的,後續應該會出一篇關於使用 Chrome-devtools 的指南。固然,本篇文章仍然存在諸多不足,歡迎提 issue ~

寫做不易,若是你以爲有收穫的話,能夠帥氣三連擊!!!

相關文章
相關標籤/搜索