面試官: 輸入U(xiǎn)rl到展示的完整過程
當(dāng)我們?cè)跒g覽器地址欄輸入一個(gè) URL 并按下回車,頁(yè)面加載的過程中會(huì)涉及多個(gè)關(guān)鍵步驟,包括 DNS 解析、TCP 連接、HTTP 請(qǐng)求、服務(wù)器處理、瀏覽器渲染 等。下面是詳細(xì)的執(zhí)行流程:
1. 用戶輸入 URL
用戶在瀏覽器地址欄輸入一個(gè) URL,例如:
https://www.example.com
- 如果 URL 沒有協(xié)議(如
http://
或https://
),瀏覽器會(huì)默認(rèn)補(bǔ)充http://
或https://
。 - 如果只輸入關(guān)鍵字(如
example
),瀏覽器會(huì)使用默認(rèn)搜索引擎查詢。 - 如果之前訪問過,瀏覽器可能直接從緩存加載(強(qiáng)緩存 / 協(xié)商緩存)。
2. 瀏覽器進(jìn)行 DNS 解析
目標(biāo):找到
www.example.com
對(duì)應(yīng)的 IP 地址
瀏覽器首先檢查是否已有緩存:
- 瀏覽器緩存(DNS 解析緩存)
- 操作系統(tǒng)緩存(
/etc/hosts
或C:\Windows\System32\drivers\etc\hosts
) - 路由器緩存(路由器可能有 DNS 解析緩存)
- ISP DNS 服務(wù)器(向本地 ISP 運(yùn)營(yíng)商的 DNS 服務(wù)器查詢)
- 根 DNS 服務(wù)器 → 頂級(jí)域名服務(wù)器(TLD) → 權(quán)威 DNS 服務(wù)器,最終獲取 IP 地址。
最終,www.example.com
被解析為 IP 地址,例如:
93.184.216.34
3. 建立 TCP 連接(三次握手)
目標(biāo):客戶端與服務(wù)器建立可靠的 TCP 連接
瀏覽器通過 TCP 三次握手 與服務(wù)器建立連接:
- 客戶端發(fā)送 SYN(請(qǐng)求建立連接)
- 服務(wù)器返回 SYN-ACK(確認(rèn)連接請(qǐng)求)
- 客戶端返回 ACK(連接建立)
如果是 HTTPS,還需要進(jìn)行 TLS/SSL 握手:
- 服務(wù)器提供 SSL 證書,客戶端驗(yàn)證證書有效性(防止中間人攻擊)。
- 雙方協(xié)商加密算法,交換密鑰,確保數(shù)據(jù)安全。
4. 發(fā)送 HTTP 請(qǐng)求
目標(biāo):瀏覽器請(qǐng)求服務(wù)器上的頁(yè)面資源
瀏覽器向服務(wù)器發(fā)送 HTTP 請(qǐng)求,例如:
GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html
Connection: keep-alive
關(guān)鍵部分:
GET
:請(qǐng)求方法(也可能是POST
、PUT
、DELETE
)。Host: www.example.com
:服務(wù)器主機(jī)名(虛擬主機(jī))。User-Agent
:瀏覽器信息。Accept
:告訴服務(wù)器客戶端希望接收的資源類型。Connection: keep-alive
:保持 TCP 連接,避免重復(fù)建立連接。
5. 服務(wù)器處理請(qǐng)求
目標(biāo):服務(wù)器解析請(qǐng)求,并返回對(duì)應(yīng)的 HTML 頁(yè)面
服務(wù)器收到請(qǐng)求后,執(zhí)行以下操作:
- 查找緩存(CDN / 服務(wù)器緩存 / 代理緩存)。
- 請(qǐng)求靜態(tài)資源(如果請(qǐng)求的是 HTML、CSS、JS、圖片)。
- 執(zhí)行動(dòng)態(tài)代碼(如 PHP、Node.js、Python 生成 HTML)。
- 訪問數(shù)據(jù)庫(kù)(如 MySQL、MongoDB)查詢數(shù)據(jù)并返回頁(yè)面。
- 生成 HTTP 響應(yīng),例如:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1024
Cache-Control: max-age=3600
并返回 HTML 內(nèi)容。
6. 瀏覽器解析 HTML
目標(biāo):瀏覽器解析 HTML 結(jié)構(gòu),構(gòu)建頁(yè)面
瀏覽器解析 HTML 頁(yè)面時(shí),執(zhí)行以下步驟:
- 解析 HTML,構(gòu)建 DOM 樹
- 解析 CSS,生成 CSSOM 樹
- 解析 JavaScript
a.如果 script
不是 async/defer
,會(huì) 阻塞解析
b.async
:異步加載并立即執(zhí)行
c.defer
:異步加載,等 HTML 解析完成后執(zhí)行
- 合并 DOM 和 CSSOM,構(gòu)建渲染樹
- 計(jì)算布局(Layout)
a.確定元素的大小、位置
- 繪制(Painting)
a.將元素渲染到屏幕
7. 加載外部資源
目標(biāo):加載 CSS、JS、圖片等外部資源
- CSS:影響頁(yè)面布局,會(huì)阻塞渲染(但不會(huì)阻塞 HTML 解析)。
- JS:
a.可能修改 DOM(導(dǎo)致重排)。
b.async
/defer
可優(yōu)化加載順序。
- 圖片、視頻、字體:
- 通過 Lazy Loading 延遲加載,提高性能。
8. 瀏覽器渲染頁(yè)面
最終,瀏覽器將渲染完成的頁(yè)面 繪制到屏幕:
- 柵格化(分成像素塊)。
- 合成圖層(不同層級(jí)合成)。
- GPU 加速(硬件加速渲染)。
9. 用戶交互 & 瀏覽器事件
- JS 監(jiān)聽用戶事件(點(diǎn)擊、滾動(dòng)等)。
- 瀏覽器根據(jù)用戶操作重新渲染頁(yè)面(如
requestAnimationFrame
)。 - 回流(Reflow)和重繪(Repaint):
a.回流:布局改變(影響性能)。
b.重繪:顏色、陰影等改變(較輕量)。
關(guān)鍵優(yōu)化點(diǎn)
- 使用 CDN 加速(減少 DNS 解析時(shí)間)。
- 開啟 HTTP/2(支持多路復(fù)用,減少 TCP 連接)。
- 開啟 Gzip 壓縮(減少 HTML/CSS/JS 體積)。
- 利用緩存(
Cache-Control
、ETag
)。 - 減少 DOM 操作(避免回流、重繪)。
- 懶加載 & 代碼拆分(按需加載資源)。
總結(jié):輸入 URL 到頁(yè)面展示的完整流程
步驟 | 過程 |
1. 輸入 URL | 用戶在瀏覽器地址欄輸入 URL |
2. DNS 解析 | 獲取域名對(duì)應(yīng)的 IP 地址 |
3. TCP 連接 | 三次握手建立 TCP 連接(HTTPS 需要 TLS 握手) |
4. 發(fā)送 HTTP 請(qǐng)求 | 瀏覽器向服務(wù)器請(qǐng)求 HTML 頁(yè)面 |
5. 服務(wù)器處理請(qǐng)求 | 服務(wù)器查詢數(shù)據(jù)庫(kù) / 讀取緩存,并返回 HTML |
6. 瀏覽器解析 HTML | 解析 DOM、CSSOM、執(zhí)行 JS,構(gòu)建渲染樹 |
7. 加載外部資源 | 加載 CSS、JS、圖片等 |
8. 渲染頁(yè)面 | 計(jì)算布局,繪制到屏幕 |
9. 用戶交互 | 監(jiān)聽點(diǎn)擊、滾動(dòng)等事件,并更新 UI |
面試官可能的追問
? 面試官:DNS 解析過程中有哪些優(yōu)化手段?
回答:
- 使用 DNS 預(yù)解析(
<link rel="dns-prefetch" >
)。 - 使用 CDN,讓用戶訪問最近的服務(wù)器。
- 配置 本地 hosts 文件,減少 DNS 查詢時(shí)間。
? 面試官:如何優(yōu)化瀏覽器渲染性能?
回答:
- 減少回流(Reflow):避免頻繁修改 DOM 結(jié)構(gòu)。
- 使用
requestAnimationFrame
:優(yōu)化動(dòng)畫流暢度。 - 使用
will-change
:讓 GPU 預(yù)渲染關(guān)鍵元素。
? 面試官:為什么 JS 可能會(huì)阻塞頁(yè)面渲染?
回答:
- JS 可能修改 DOM,瀏覽器必須先執(zhí)行 JS,再繼續(xù)解析 HTML。
- 解決方案:使用
async
/defer
,或?qū)?JS 放在body
末尾。
總結(jié)
輸入 URL 到頁(yè)面展示的過程涉及 DNS 解析、TCP 連接、HTTP 請(qǐng)求、服務(wù)器處理、瀏覽器解析和渲染等多個(gè)步驟。通過優(yōu)化緩存、CDN、HTTP/2 和瀏覽器渲染策略,可以極大提高頁(yè)面加載速度!??