對於面試常問的從瀏覽器輸入 URL
到頁面展現過程發生了什麼?,我想你們都或多或少能說出一二。可是,其實這個問題頗有深度,而你是否回答的有深度,在很大程度上會影響到面試官對你的印象。javascript
而且,網上各類資料都是淺嘗輒止地講解這個過程,常常會出現今天看到這個版本,明天看到另外一個版本地狀況。因此,此次咱們就來深刻淺出一下這整個過程~css
首先,在開始講解整個過程前,咱們須要認識一下 Chrome
多進程架構。由於,從瀏覽器輸入 URL
到頁面渲染的整個過程都是由 Chrome
架構中的各個進程之間的配合完成。html
Chrome
的多進程架構:java
HTML
文檔和
JavaScript
等轉化爲用戶界面
HTTP
請求、
WebSocket
模塊
GPU
(圖形處理器)進程,它負責對
UI
界面的展現
發生這個過程的前提,用戶在地址欄中輸入了 URL
,而地址欄會根據用戶輸入,作出以下判斷:node
URL
結構的字符串,則會用瀏覽器默認的搜索引擎搜索該字符串
URL
結構字符串,則會構建完整的
URL
結構,瀏覽器進程會將完整的
URL
經過進程間通訊,即
IPC
,發送給網絡進程
在網絡進程接收到 URL
後,並非立刻對指定 URL
進行請求。首先,咱們須要進行 DNS
解析域名獲得對應的 IP
,而後經過 ARP
解析 IP
獲得對應的 MAC
(Media Access Control Address
)地址。web
域名是咱們取代記憶複雜的
IP
的一種解決方案,而IP
地址纔是目標在網絡中所被分配的節點。MAC
地址是對應目標網卡所在的固定地址。面試
1. DNS 解析瀏覽器
而 DNS
解析域名的過程分爲如下幾個步驟:緩存
DNS
緩存
DNS
緩存(即查找本地
host
文件)
ISP
(
Internet Service Provider
)互聯網服務提供商(例如電信、移動)的
DNS
服務器
2. 通訊過程安全
首先,創建 TCP
鏈接,即三次握手過程:
SYN
的數據包,表示我將要發送請求。
SYN/ACK
的數據包,表示我已經收到通知,告知客戶端發送請求。
ACK
的數據包,表示我要開始發送請求,準備被接受。
而後,利用 TCP
通道進行數據傳輸:
TCP
的
重發機制
TCP
頭中的須要進行
排序,造成完整的數據
最後,斷開 TCP
鏈接,即四次握手過程:
而這整個過程的客戶端則是網絡進程。而且,在數據傳輸的過程還可能會發生的重定向的狀況,即當網絡進程接收到狀態碼爲 3xx 的響應報文,則會根據響應報文首部字段中的 Location 字段的值進行重定向,即會從新發起請求
3. 數據處理
當網絡進程接收到的響應報文狀態碼,進行相應的操做。例如狀態碼爲 200 OK
時,會解析響應報文中的 Content-Type
首部字段,例如咱們這個過程 Content-Type
會出現 application/javascript
、text/css
、text/html
,即對應 Javascript
文件、CSS
文件、HTML
文件。
詳細的
MIME
類型講解能夠看 MDN
當前須要渲染 HTML
時,則須要建立渲染進程,用於後期渲染 HTML
。而對於渲染進程,若是是同一站點是能夠共享一個渲染進程,例如 a.abc.com
和 c.abc.com
能夠共享一個渲染渲染進程。不然,須要從新建立渲染進程
須要注意的是,同站指的是頂級域名和二級域名相等
在建立完渲染進程後,網絡進程會將接收到的 HTML、JavaScript 等數據傳遞給渲染進程。而在渲染進程接收完數據後,此時用戶界面上會發生這幾件事:
URL
enable
,顯示正在加載狀態
你們都知道頁面渲染的過程也是面試中單獨會考的點,而且時常會由這個點延申出另外一個問題,即如何避免迴流和重繪。
渲染過程,是整個從瀏覽器輸入 URL 到頁面渲染過程的最後一步。而頁面渲染的過程能夠分爲 9 個步驟:
HTML
生成
DOM
樹
CSS
生成
CSSOM
JavaScript
Render Tree
)
因爲網絡進程傳輸給渲染進程的是 HTML
字符串,因此,渲染進程須要將 HTML
字符串轉化成 DOM
樹。例如:
須要注意的是這個
DOM
樹不一樣於Chrome-devtool
中Element
選項卡的DOM
樹,它是存在內存中的,用於提供JavaScript
對DOM
的操做。
構建 CSSOM
的過程,即經過解析 CSS
文件、style
標籤、行內 style
等,生成 CSSOM
。而這個過程會作這幾件事:
CSS
,即將
color: blue
轉化成
color: rgb()
形式,能夠理解成相似
ES6
轉
ES5
的過程
CSS
樣式會繼承父級的樣式,如
font-size
、
color
之類的。
CSS Object Model
是一組容許用JavaScript
操縱CSS
的API
。詳細API
講解能夠看 MDN
一般狀況下,在構建 DOM
樹或 CSSOM
的同時,若是也要加載 JavaScript
,則會形成前者的構建的暫停。固然,咱們能夠經過 defer
或 sync
來實現異步加載 JavaScript
。雖然 defer
和 sync
均可以實現異步加載 JavaScript
,可是前者是在加載後,等待 CSSOM
和 DOM
樹構建完後才執行 JavaScript
,然後者是在異步加載完立刻執行,即便用 sync
的方式仍然會形成阻塞。
而 JavaScript
執行的過程,即編譯和運行 JavaScript
的過程。因爲 JavaScript
是解釋型的語言。因此這個過程會是這樣的:
Token
化
Token
,生成
AST
(
Abstract Sytanx Tree
) 抽象語法樹和建立上下文
AST
,生成字節碼。
在有了 DOM
樹和 CSSOM
以後,須要將二者結合生成渲染樹 Render Tree
,而且這個過程會去除掉那些 display: node
的節點。此時,渲染樹就具有元素和元素的樣式信息。
根據 Render Tree
渲染樹,對樹中每一個節點進行計算,肯定每一個節點在頁面中的寬度、高度和位置。
須要注意的是,第一次肯定節點的大小和位置的過程稱爲佈局,而第二次才被稱爲迴流
因爲層疊上下文的存在,渲染引擎會爲具有層疊上下文的元素建立對應的圖層,而諸多圖層的疊加就造成了咱們看到的一些頁面效果。例如,一些 3D
的效果、動畫就是基於圖層而造成的。
值得一提的是,對於內容溢出存在滾輪的狀況也會進行分層
對於存在圖層的頁面部分,須要進行有序的繪製,而對於這個過程,渲染引擎會將一個個圖層的繪製拆分紅繪製指令,並按照圖層繪製順序造成一個繪製列表。
有了繪製列表後,渲染引擎中的合成線程會根據當前視口的大小將圖層進行分塊處理,而後合成線程會對視口附近的圖塊生成位圖,即光柵化。而渲染進程也維護了一個柵格化的線程池,專門用於將圖塊轉爲位圖。
光柵化的過程一般會使用
GPU
加速,例如使用wil-change
、opacity
,就會經過GPU
加速顯示
當全部的圖塊都通過柵格化處理後,渲染引擎中的合成線程會生成繪製圖塊的指令,提交給瀏覽器進程。而後瀏覽器進程將頁面繪製到內存中。最後將內存繪製結果顯示在用戶界面上。
而這個整個從生成繪製列表、光柵化、顯示的過程,就是咱們常說的重繪的過程
整個瀏覽器輸入 URL 到頁面渲染的過程涉及到的知識點很是廣,如 Chrome
多進程的架構、HTTP
通訊過程、瀏覽器解析 JavaScript
過程、瀏覽器繪製頁面過程以及一些計算機的基礎知識等等,而且,這整個過程的分析其實和 Chrome-devtools
密切相關,因此很好的使用 Chrome-devtools
是很是重要的,後續應該會出一篇關於使用 Chrome-devtools
的指南。固然,本篇文章仍然存在諸多不足,歡迎提 issue
~
寫做不易,若是你以爲有收穫的話,能夠帥氣三連擊!!!