你有沒有想過,當你輸入一個 URL 並按下 Enter 鍵時,瀏覽器背後究竟發生了什麼事?從外部看,這一切看似簡單,但背後卻隱藏著一個非常複雜的工程流程,涉及多個步驟、層級和協定。在本文中,我們將探索瀏覽器的工作原理及其內部架構的設計。
一個瀏覽器可以理解分成幾個重要的部分:
使用者介面 (UI):與使用者互動的層,指您直接看到和互動的一切,例如網址列、導覽按鈕和標籤。
瀏覽器引擎:瀏覽器的核心引擎。它將使用者介面與其他瀏覽器元件連接起來。它還負責資料持久化(Cookie、快取、本地儲存)並與渲染引擎進行通訊。
渲染引擎:負責在螢幕上渲染內容。該元件與 JS 解釋器和網路層協同工作,將 HTML、CSS 和 JavaScript 轉換為可見像素。
網路:管理 HTTP/HTTPS 請求、DNS 解析、cookie、快取、資料壓縮以及連接的所有安全措施。
JavaScript 解釋器:解析、編譯並執行 JS 程式碼:解析、建立抽象語法樹 (AST)、轉換為字節碼、套用 JIT 最佳化並在 JS 虛擬機器上執行。這支援 DOM 操作、事件處理和頁面互動。
資料持久性:允許瀏覽器在本機上儲存和檢索資料,確保使用者資料、設定和首選項在會話期間得到維護。
值得注意的是,瀏覽器基本上是單線程的。這意味著只有一個主執行緒控制流程,這在討論效能時至關重要。為了克服這一限制,瀏覽器使用了諸如事件循環之類的機制,這與我們在 Node.js 中了解到的機制非常相似。
輸入 URL 並按下 Enter 鍵後,將發生以下步驟:
網域解析(DNS):
第一步是將網域名稱(例如 google.com)轉換為 IP 位址。瀏覽器會檢查各種快取(瀏覽器、作業系統、路由器、ISP)。
如果找不到,它會查詢 DNS 伺服器,DNS 伺服器會傳回正確的 IP。
伺服器連線(TCP握手):
取得IP後,瀏覽器透過TCP三次握手建立連線:
SYN→SYN-ACK→ACK。
可以將其視為開始電話交談的數位等價物。
使用 TLS 握手的安全性:
在交換資料之前,必須建立安全的加密金鑰。這涉及客戶端和伺服器之間的多次訊息交換,以確保流量不會被攔截。
邊緣運算和CDN:
為了加快這一速度,Google、Netflix 和亞馬遜等公司在全球範圍內使用 CDN 和邊緣位置,以減少用戶和伺服器之間的延遲。
首次回應 – TTFB:
一切設定完成後,瀏覽器會收到第一個位元組(第一個位元組時間)。甚至在完整頁面載入完成之前,渲染就開始了。
當瀏覽器收到初始 HTML 時,它開始解析。過程包括:
DOM 建構:HTML 被轉換為稱為文件物件模型的樹狀結構。
CSSOM 建構:CSS 也被解析成一棵樹,也就是 CSS 物件模型。與 DOM 不同,它必須完全建造後才能繼續。
渲染樹:DOM + CSSOM 組合成渲染樹,其中僅包含具有計算樣式的可見元素。
佈局:決定螢幕上每個元素的位置和大小。
繪畫:最後,在螢幕上繪製像素。
此流程稱為關鍵渲染路徑 (CRP)。腳本可能會阻塞 DOM 建置,樣式可能會延遲 CSSOM 建置。因此,腳本的 async 和 defer 等技術可以提高載入速度。
在建置 DOM 時,瀏覽器會執行預先載入掃描器,它會尋找 HTML 中引用的外部資源(圖片、腳本、樣式)。這些資源會提前下載,從而減少整體渲染時間。
JavaScript 和 AST
與編譯型語言不同,JavaScript 是解釋型語言,但現代瀏覽器對執行進行了最佳化:
解析:程式碼被解析為抽象語法樹(AST)。
字節碼和 JIT:AST 被轉換為字節碼,由即時 (JIT) 編譯器最佳化,然後由 JS 虛擬機器執行。
執行:延遲和阻塞腳本僅在 HTML 和 CSS 準備好後執行,以確保更快的初始渲染。
HTML 文件可以在記憶體中表示為 JavaScript 樹(節點和子節點)。這使得框架、庫和開發人員可以即時操作頁面。
例子:
const domTree = {
nodeType: 'document',
children: [
{ nodeType: 'doctype', name: 'html' },
{
tagName: 'html',
attributes: { lang: 'en' },
children: [
{
tagName: 'head',
children: [
{ tagName: 'meta', attributes: { charset: 'utf-8' }, children: [] },
{ tagName: 'meta', attributes: { name: 'viewport', content: 'width=device-width, initial-scale=1' }, children: [] },
{ tagName: 'title', children: [{ type: 'text', content: 'Page Title' }] },
{ tagName: 'link', attributes: { rel: 'stylesheet', href: '/styles.css' }, children: [] },
{ tagName: 'script', attributes: { src: '/scripts/head.js', defer: true }, children: [] }
]
},
{
tagName: 'body',
children: [
{
tagName: 'header',
children: [
{ tagName: 'h1', children: [{ type: 'text', content: 'Main Header' }] },
{
tagName: 'nav',
children: [
{
tagName: 'ul',
children: [
{ tagName: 'li', children: [{ tagName: 'a', attributes: { href: '/' }, children: [{ type: 'text', content: 'Home' }] }] },
{ tagName: 'li', children: [{ tagName: 'a', attributes: { href: '/about' }, children: [{ type: 'text', content: 'About' }] }] }
]
}
]
}
]
},
{
tagName: 'main',
children: [
{
tagName: 'article',
attributes: { id: 'post-1' },
children: [
{ tagName: 'h2', children: [{ type: 'text', content: 'Article Title' }] },
{ tagName: 'p', children: [{ type: 'text', content: 'First paragraph of the article.' }] },
{ tagName: 'img', attributes: { src: '/img/photo.jpg', alt: 'Photo' }, children: [] }
]
},
{
tagName: 'section',
attributes: { id: 'features' },
children: [
{ tagName: 'h3', children: [{ type: 'text', content: 'Features Section' }] },
{
tagName: 'ul',
children: [
{ tagName: 'li', children: [{ type: 'text', content: 'Feature A' }] },
{ tagName: 'li', children: [{ type: 'text', content: 'Feature B' }] }
]
}
]
}
]
},
{
tagName: 'aside',
children: [
{ tagName: 'h4', children: [{ type: 'text', content: 'Sidebar' }] },
{ tagName: 'p', children: [{ type: 'text', content: 'Supporting content / widgets.' }] }
]
},
{
tagName: 'footer',
children: [
{ tagName: 'p', children: [{ type: 'text', content: '© 2025 My Company' }] },
{ tagName: 'ul', children: [{ tagName: 'li', children: [{ tagName: 'a', attributes: { href: '/privacy' }, children: [{ type: 'text', content: 'Privacy Policy' }] }] }] }
]
},
{ tagName: 'script', attributes: { src: '/scripts/bundle.js' }, children: [] }
]
}
]
}
]
};
此外,DOM 並非靜態的。瀏覽器可能會在下載新資源的同時逐步建立它。這使得 DOM 成為一個即時的動態結構,完全可以透過 JavaScript API 進行操作。
為了呈現單一網頁,瀏覽器需要經歷一個龐大的過程,其中包括:
解析域名
執行多次握手
處理安全協議
建立 DOM 和 CSSOM 樹
產生渲染樹、佈局和繪製
執行優化的 JavaScript
所有這些都發生在幾分之一秒內。本文的靈感來自 Augusto Galego 的精彩影片《瀏覽器是如何運作的? 》,他在影片中以清晰易懂的方式解釋了這些主題。當然,瀏覽器功能還涉及許多其他層面,從頭開始建立一個瀏覽器將是一項極其複雜的任務。
如果你讀到這裡,非常感謝!任何回饋都將不勝感激。
原文出處:https://dev.to/giovanni786/how-a-web-browser-works-inside-modern-browsers-3j8d