cover

瀏覽器請求流程圖

你每天打開瀏覽器、輸入網址、按下 Enter,整個頁面就「啪」地出現在眼前。但你有沒有想過,從按下 Enter 到看到畫面的那不到一秒鐘裡,背後到底發生了多少事?這個問題不只是面試愛考——理解這個流程,會讓你在做效能優化、除錯網路問題時有完全不同的視野。

當我們在瀏覽器輸入網址並按下 Enter,到網頁完整呈現在眼前,這中間究竟發生了什麼事?

完整流程

┌─────────────────────────────────────────────────────────────┐
│  1. 使用者輸入 URL                                           │
│     ↓                                                        │
│  2. DNS 解析(域名 → IP 位址)                               │
│     ↓                                                        │
│  3. TCP 三次握手(建立連線)                                  │
│     ↓                                                        │
│  4. TLS 握手(如果是 HTTPS)                                 │
│     ↓                                                        │
│  5. 發送 HTTP 請求                                           │
│     ↓                                                        │
│  6. 伺服器處理請求                                           │
│     ↓                                                        │
│  7. 伺服器回傳 HTTP 回應                                     │
│     ↓                                                        │
│  8. 瀏覽器解析 HTML                                          │
│     ↓                                                        │
│  9. 下載並解析 CSS、JavaScript、圖片等資源                   │
│     ↓                                                        │
│  10. 渲染頁面                                                │
└─────────────────────────────────────────────────────────────┘

Step 1: URL 解析

瀏覽器首先解析你輸入的 URL:

https://www.example.com:443/path/page.html?query=value#section
  │          │           │        │              │        │
  │          │           │        │              │        └─ Fragment(錨點)
  │          │           │        │              └─ Query String(查詢參數)
  │          │           │        └─ Path(路徑)
  │          │           └─ Port(連接埠,HTTPS 預設 443)
  │          └─ Host(主機名稱)
  └─ Protocol(協定)

Step 2: DNS 解析

瀏覽器需要將域名轉換為 IP 位址:

  1. 瀏覽器快取:檢查是否有快取的 DNS 記錄
  2. 作業系統快取:檢查 OS 的 DNS 快取
  3. 路由器快取:詢問路由器
  4. ISP DNS 伺服器:詢問網路供應商的 DNS
  5. 遞迴查詢:從根域名伺服器開始查詢
www.example.com
     ↓
根域名伺服器 → .com 域名伺服器 → example.com 權威伺服器
     ↓
93.184.216.34

Step 3: TCP 三次握手

建立可靠的 TCP 連線:

客戶端                          伺服器
   │                               │
   │ ──── SYN (seq=x) ────────→   │  1. 客戶端發送 SYN
   │                               │
   │ ←── SYN-ACK (seq=y, ack=x+1)  │  2. 伺服器回應 SYN-ACK
   │                               │
   │ ──── ACK (ack=y+1) ───────→  │  3. 客戶端確認 ACK
   │                               │
   │      連線建立完成              │

Step 4: TLS 握手(HTTPS)

如果是 HTTPS,還需要進行 TLS 握手:

  1. Client Hello:客戶端發送支援的加密方式
  2. Server Hello:伺服器選擇加密方式,發送憑證
  3. 驗證憑證:客戶端驗證伺服器憑證
  4. 金鑰交換:交換對稱加密金鑰
  5. 加密通訊開始

Step 5: 發送 HTTP 請求

GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0
Accept: text/html,application/xhtml+xml
Accept-Language: zh-TW,zh;q=0.9,en;q=0.8
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

Step 6-7: 伺服器處理與回應

伺服器收到請求後:

  1. 路由處理
  2. 執行業務邏輯
  3. 查詢資料庫(如需要)
  4. 產生 HTML 內容
  5. 回傳 HTTP 回應
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 1234
Cache-Control: max-age=3600
 
<!DOCTYPE html>
<html>...

到這裡為止都是「網路層」的事情。接下來,資料終於到了瀏覽器手上,輪到它把一堆文字和程式碼變成你看到的漂亮畫面了。

Step 8-10: 瀏覽器渲染

關鍵渲染路徑(Critical Rendering Path)

HTML → DOM Tree
              ↘
                → Render Tree → Layout → Paint → Composite
              ↗
CSS → CSSOM
  1. 解析 HTML:建立 DOM Tree
  2. 解析 CSS:建立 CSSOM
  3. 合併:DOM + CSSOM = Render Tree
  4. Layout:計算每個元素的位置和大小
  5. Paint:繪製像素到螢幕
  6. Composite:合成多個圖層

JavaScript 的影響

  • 阻塞解析:遇到 <script> 標籤會暫停 HTML 解析
  • async:非同步載入,載入完立即執行
  • defer:非同步載入,等 HTML 解析完才執行
<!-- 阻塞 -->
<script src="app.js"></script>
 
<!-- 非同步,載入完立即執行 -->
<script async src="analytics.js"></script>
 
<!-- 非同步,DOM 完成後執行 -->
<script defer src="app.js"></script>

效能優化建議

階段優化方法
DNSDNS 預解析 <link rel="dns-prefetch">
連線預連線 <link rel="preconnect">
請求減少 HTTP 請求、使用 HTTP/2
回應啟用 Gzip、使用 CDN
渲染CSS 放頭部、JS 放底部或 defer

延伸閱讀