---
schemaVersion: 1
slug: levelup-20260621-16-browser-moba-multiprocess
ticketId: Lv-16
lang: zh-tw
title: 瀏覽器其實是一支五人隊（上）：為什麼一個分頁當掉，不會帶走整個瀏覽器
summary: 你以為瀏覽器是一個程式？其實它是一支分工的隊伍：一個隊長指揮全場、一個打野去網路刷資源、每個網站派一個英雄守自己那條線。這篇用一局 MOBA 的角度，講瀏覽器的多進程架構、網站隔離和沙箱——也就是為什麼某個分頁吃滿記憶體當掉，整個瀏覽器不會跟著陪葬。
originalDate: 2026-06-21
translatedDate: 2026-06-21
source: Addy Osmani
sourceUrl: https://x.com/addyosmani/status/2068394292796871019
author: null
authorshipNote: null
canonicalUrl: https://gu-log.vercel.app/posts/levelup-20260621-16-browser-moba-multiprocess
status: published
replacementTicketId: null
replacementUrl: null
---

# 瀏覽器其實是一支五人隊（上）：為什麼一個分頁當掉，不會帶走整個瀏覽器

> **來源:** [Addy Osmani](https://x.com/addyosmani/status/2068394292796871019)

想像一下 2007 年，畫面上開著十個分頁在趕報告。其中一個分頁的廣告，跑了一行寫爛的程式碼。下一秒——**整個瀏覽器連同那十個分頁，一起消失。** 還沒存的東西，蒸發了。

那個年代，瀏覽器是「一個程式」，全家共用一條命，一個人踩雷全隊陪葬。

今天不會了。某個分頁吃滿記憶體、卡到當掉，只要關掉那一個，其他分頁眨都不眨一下。這中間到底發生了什麼事？答案一句話就能講完，而且它會改變一般人看瀏覽器的方式：**瀏覽器從「一個程式」，變成了一支分工的隊伍。**

按下 `Enter` 那一刻，螢幕後面動起來的不是「一個瀏覽器」，而是**一整支隊**——有人指揮、有人去野區刷資源、有人守線、有人負責把畫面打出來。它們各自是獨立的進程，各自有自己的記憶體、自己的生死，彼此之間只能隔著一道牆喊話。開五個分頁，工作管理員裡可能跳出十幾個 `chrome` 進程——那不是壞掉，那是設計。

這篇（上集）就用一局 MOBA 的角度，把這支隊伍的選角表攤開來，順便回答一個一般人每天都在受惠、卻沒想過的問題：**為什麼某個分頁跑到當掉、吃滿記憶體，只要關掉那一個分頁，其他分頁跟整個瀏覽器都還活得好好的？**

（下集會接著講這支隊伍怎麼打「團戰」——也就是一次畫面更新背後的繪製流程。先把隊伍認熟。）

---

## 🏰 第 0 層：全景圖 — 瀏覽器是一支隊，不是一個人

**Level 0 / 5 — 瀏覽器這支五人隊（上） — 0% 完成**

先看全貌。一個現代 Chrome 瀏覽器，至少拆成這幾種角色，每一種都是一個獨立進程：

```mermaid
graph TD
    A[隊長 / 指揮<br/>管 UI、發號施令] --> B[打野<br/>去網路刷資源]
    A --> C[守線英雄 1<br/>網站 A 的分頁]
    A --> D[守線英雄 2<br/>網站 B 的分頁]
    A --> E[輸出核心<br/>把畫面打到螢幕]
    A --> F[工具人 / 輔助<br/>解碼、擴充功能…]
```

_瀏覽器的多進程架構，用一支 MOBA 隊伍來看_

注意所有箭頭都從「隊長」出去——它是唯一的中央協調者，是它生出其他所有進程的。其他角色彼此**不能直接講話**，要溝通只能透過隊長轉達（這個轉達機制叫跨進程通訊，`IPC`，下面會提到）。

> **一局的開場**
>
> 想像排到一場 5v5。系統不會丟五個一模一樣的人進去，而是分配好位置：
>
> - **隊長/指揮**：站後排喊指令、看大局，自己不太下去拚刀
> - **打野**：在野區跑來跑去，把資源刷回來餵給隊友
> - **守線英雄**：一人顧一條線，正面對線、最辛苦也最危險
> - **輸出核心**：負責把隊友創造的優勢，轉換成「實際打死人」的傷害
> - **輔助/工具人**：做雜事、補位、處理沒人想碰的髒活
>
> 瀏覽器這支隊，分工幾乎一模一樣。把這張對照表記起來，下面整篇都靠它。

> **Mogu 想補充：**
>
> 你可能會問：好好一個瀏覽器，幹嘛搞得像在打電動分位置這麼麻煩？一個進程把全部事情做完不就好了？
>
> 問得好，而這正是 2008 年以前所有瀏覽器的做法——**全隊共用一條命**。結果就是下面第 2 層要講的慘案。先賣個關子：那個年代你開十個分頁，其中一個網頁寫了爛 code 崩潰，會發生什麼事？答案不是「那個分頁掛掉」，是「你十個分頁一起陪葬，整個瀏覽器當場關閉」(╯°□°)╯

---

## 🏰 第 1 層：選角表 — 五個角色，各司其職

**Level 1 / 5 — 瀏覽器這支五人隊（上） — 20% 完成**

把每個角色拆開來看。每個角色後面括號裡是它在瀏覽器架構裡的正式名字，認一次就好，之後整篇都用中文角色名喊它。

**1. 隊長 / 指揮（`Browser Process`）**

這是整支隊的中央大腦，也是一般人「以為的那個瀏覽器」。它負責所有**網頁以外**的東西：網址列、書籤、選單、分頁標籤、上一頁下一頁這些按鈕。它不負責畫網頁內容，但它**指揮**所有負責畫的人，並且管理導航、協調資源載入。在工作管理員看到的「那一個 Chrome」，就是它。

**2. 打野（`Network Service`）**

當守線英雄需要資源（HTML、CSS、JS、圖片）時，它**不會自己跑去網路上抓**。它得拜託打野。打野專門處理所有網路請求、DNS、`socket` 連線這些底層髒活，刷回來再交給對應的英雄。

這個分工有個關鍵的資安意義：**守線英雄碰不到網路，只能跟打野要。** 為什麼這很重要，第 3、4 層會講。

**3. 守線英雄（`Renderer Process`，主角）**

這是整篇的主角。**每一個分頁（更精確地說，每一個網站）都派一個守線英雄。** 它跑 `Blink` 排版引擎跟 V8 這個 JavaScript 引擎，負責把網頁的 HTML 解析成 DOM、跑網頁的 JS、算排版、把畫面準備好。

它是**最辛苦也最危險**的角色——因為它跑的是「來自網路、完全不受信任的程式碼」。隨便哪個網站塞給它的 JS，它都得乖乖執行。所以守線英雄被關得最緊（第 4 層的沙箱）。

**4. 輸出核心（`GPU Process`）**

守線英雄把畫面「準備」好之後，最後一哩——真正把一個個像素點到螢幕上——是輸出核心幹的。它是唯一一個直接跟顯卡（GPU）講話的角色，所有英雄的畫面、連同隊長那層外殼介面，最後都送到它這裡合成、輸出。

**5. 工具人 / 輔助（`Utility Process`）**

剩下的雜活：解碼影音、跑擴充功能、處理儲存等等，各自再拆成獨立的小進程。原則是：**只要那件事有風險（譬如解一個來路不明的影片檔），就把它隔離出去單獨關一間。**

> **Mogu 歪樓一下：**
>
> 有沒有發現一個 pattern：危險的事，全部外包給「可以隨時被開除、開除了也不影響大局」的獨立進程。
>
> 這其實是寫任何系統都通用的智慧——**把不受信任、容易出事的部分，跟你的核心隔離開**。瀏覽器只是把這個原則做到極致：連「解一個影片檔」這種小事都怕，寧可多開一個進程關起來解。聽起來很神經質？是有點。但你想想瀏覽器每天要吞多少來路不明的東西，神經質剛剛好 ʕ•ᴥ•ʔ

**Quiz:** 守線英雄想抓一張網路上的圖片，它會怎麼做？

- A. 自己開 socket 連網路，想載什麼就載什麼
- B. 從自己的硬碟快取撈，根本不碰網路
- C. 拜託打野（網路進程）去抓，再把資料交回來
- D. 對著螢幕念咒，圖片自己浮出來

**Answer:** C — 守線英雄被關在沙箱裡、碰不到網路，這是故意的——所以 A 的『自己連網路』正好是它最不能做的事。它也沒有能繞過網路的私人硬碟快取（B）。所有資源都得透過打野（網路進程）代拿；萬一這個英雄被惡意網站攻破，它連網路的鑰匙都沒有，資料偷不出去。

---

## 🏰 第 2 層：為什麼要拆成一支隊 — 單進程時代的「共一條命」慘案

**Level 2 / 5 — 瀏覽器這支五人隊（上） — 40% 完成**

回到 [Mogu](https://gu-log.vercel.app/glossary#mogu) 剛剛賣的關子。**2008 年以前，瀏覽器是「單進程」的——整支隊共用一條命。**

那是什麼概念？想像一局 MOBA，五個人共用同一條血條。中路的隊友手殘踩到一個地雷，結果不是他一個人死，是**全隊瞬間一起倒地、直接 GG 投降**。聽起來很荒謬，但這就是舊瀏覽器的日常：任何一個分頁的網頁寫了爛 code、跑進無窮迴圈、或踩到一個會崩潰的 bug，**整個瀏覽器連同其他開著的所有分頁，一起當場關閉。** 正在打的那篇還沒存的長文？沒了。

2008 年，Chrome 第一個把這件事翻轉過來：**多進程架構**。每個分頁派自己的守線英雄、住在自己的進程、有自己獨立的一條命。

> **一條命 vs 各有各的命**
>
> - **單進程（舊瀏覽器）**：全隊共一條血。一個人送頭 → 整隊 GG。
> - **多進程（Chrome 之後）**：每個英雄各有各的命。中路那個守線的崩了，也只是少一條線，**其他四個人照樣在場上跑**。關掉那個分頁、重開，就像把那條線的英雄重新買活，全隊繼續打。

這就是為什麼，現在某個分頁卡死、或跳出那個 Chrome 經典的「Aw, Snap!」哭臉錯誤頁，只要關掉或重新整理**那一個分頁**就好，其他分頁完全不受影響。在 2008 年以前，這是天方夜譚。

原文把多進程的好處整理成三點，用這套隊伍語言講就是：

- **穩定**：一個英雄崩潰，不會帶走全隊。
- **資安**：每個英雄關在自己的籠子裡，出事波及範圍有限（第 3、4 層的重點）。
- **效能隔離**：某條線在打一場硬仗（某個分頁跑超重的運算），不會卡住其他線——因為作業系統可以把不同進程排到不同的 CPU 核心上跑。

> **Mogu 吐槽時間：**
>
> 「Aw, Snap!」那隻哭臉，本質上是 Chrome 在跟你說：「報告隊長，中路那個守線的英雄陣亡了，但別緊張，其他人都還在，要不要我幫你把他買活（重新整理）？」
>
> 而在單進程的遠古時代，對應的訊息只有一種——整個視窗直接消失，連道別都沒有。所以下次看到那隻哭臉，別罵它，那其實是進步的象徵：它代表你的災情被控制在一條線，而不是全隊團滅 (￣▽￣)／

**Quiz:** 在單進程的舊瀏覽器年代，某一個分頁的網頁崩潰了，會發生什麼事？

- A. 整個瀏覽器連同所有分頁一起當掉
- B. 只有那個分頁掛掉，其他分頁安全沒事
- C. 瀏覽器自動幫那個分頁存檔再重開
- D. 螢幕會跳出一隻哭臉龍蝦跟你道別

**Answer:** A — 單進程 = 全隊共用一條命，一個分頁崩潰 = 整個瀏覽器陪葬。B 那種『只掛一個分頁、其他沒事』其實是 2008 年多進程架構之後才有的待遇，當年根本沒有分頁隔離。C 的自動存檔重開也不存在——崩了就是崩了，沒存的東西直接蒸發。

---

## 🏰 第 3 層：為什麼每個英雄被鎖死在自己線上 — 網站隔離（`Site Isolation`）

**Level 3 / 5 — 瀏覽器這支五人隊（上） — 60% 完成**

多進程解決了「穩定」，但還有一個更陰險的問題：**資安**。

設想一個情境：同時開了兩個分頁，一個是網路銀行，一個是某個隨手點開、其實藏了惡意程式的爛網站。如果這兩個網站的守線英雄**住在同一個進程、共用同一塊記憶體**，那個惡意網站理論上就有機會偷看到隔壁銀行分頁的記憶體內容——餘額、登入狀態、一切。

對面那個臥底，就站在銀行帳號旁邊。

Chrome 的解法叫 `Site Isolation`（網站隔離）：**不同的網站，強制住在不同的進程裡，連塞在同一個頁面裡、來自不同網域的 `iframe` 都要拆出去單獨關一間**（這個機制叫 `OOPIF`，把跨網站的 `iframe` 拆到進程外）。兩個網站的記憶體從此是兩塊完全分開的空間，臥底再怎麼翻自己的口袋，也翻不到隔壁那一間。

> **為什麼不能讓兩個英雄共用一個野區**
>
> 把「進程」想成各自獨立的野區，「記憶體」想成野區裡的資源。
>
> 如果銀行英雄跟一個來路不明的英雄共用同一個野區，那個臥底就算正面打不過，也可以偷偷摸進那個野區，把裡面的資源、視野、一切看光光。
>
> 網站隔離等於規定：**每個網站一個專屬野區，牆築死，誰都不准踏進別人的。** 銀行英雄在自己的野區裡，臥底碰不到。

為什麼 Chrome 要把這件事做到這麼絕？因為 **2018 年的 `Spectre` 漏洞**。

`Spectre` 證明了一件可怕的事：惡意的 JavaScript 可以利用 CPU 的「預測執行」這個底層機制，**偷讀到它本來不該讀到的記憶體**。換句話說，只要兩個網站還共用同一個進程，再多軟體層的防護都可能被這種 CPU 等級的攻擊繞過。**唯一真正穩的解，就是從根本上不讓它們共用進程。** 於是 Chrome 把網站隔離設成預設（大約在 Chrome 67），到 2024 年，桌面版 Chrome 有 99% 的使用者都開著它。

> **Mogu 想補充：**
>
> `Spectre` 這個漏洞屌的地方在於：它不是某個瀏覽器寫爛了，是**整個世代的 CPU 為了跑快一點，都內建了會漏資訊的機制**。不分廠牌，主流 CPU 幾乎全中。
>
> 這就像你發現整個聯盟的英雄，因為某個底層機制設計，全部都有一個共通的破綻可以被偷家。你沒辦法靠「修某一個英雄」解決，只能改規則——把每個人關進獨立的房間，從架構上根除「偷看隔壁」的可能性。網站隔離就是這個「改規則」。代價是記憶體變多（第 4 層會算這筆帳），但比起你的銀行帳號被 CPU 級的攻擊偷走，這錢花得超值 (⌐■\_■)

**Quiz:** Chrome 為什麼要把『不同網站住在不同進程』設成預設（網站隔離）？

- A. 因為一個進程比較省記憶體、比較環保
- B. 因為共用進程時，惡意網站能偷讀隔壁的記憶體
- C. 因為分進程能讓網頁載入速度變快
- D. 因為工程師很閒，想多生幾個進程來玩

**Answer:** B — 正解的根源是 2018 年的 \`Spectre\`：只要兩個網站共用一個進程，惡意 JS 就能利用 CPU 的預測執行偷讀隔壁網站的記憶體。A 剛好講反了——網站隔離不但不省記憶體，因為進程變多還會多吃約一成出頭。C 也不是重點，分進程的代價反而是更多開銷；換來的是安全，不是速度。

---

## 🏰 第 4 層：就算英雄被攻破，也偷不走東西 — 沙箱（與這支隊的伙食費）

**Level 4 / 5 — 瀏覽器這支五人隊（上） — 80% 完成**

網站隔離解決了「網站之間互相偷看」。但還有最後一道防線要處理：**萬一某個守線英雄真的被惡意網站攻破、被對面破了門——它能對這台電腦幹嘛？**

答案是：幾乎什麼都幹不了。因為每個守線英雄從一出生就被關在 **沙箱（`sandbox`）** 裡。

沙箱是一個由作業系統層級強制執行的低權限籠子（Linux 上用 `namespaces` + `seccomp` 限制系統呼叫，Windows 上用 `job object` 砍權限）。被關在裡面的守線英雄**可以盡情運算、排版、畫畫面，但一旦它想讀硬碟、開相機麥克風、或亂連網路，全部會被擋下來**。要做這些「特權操作」，它只能乖乖跟隊長報備，由隊長審核、必要時跳出權限視窗問使用者同意。

> **把臥底關進一間什麼都摸不到的房間**
>
> 就算對面成功攻破守線英雄、佔領了那個進程，它面對的下一道牆是：那個英雄被關在一間**幾乎空無一物**的房間裡。
>
> 沒有對外的門（不能直接連網路）、沒有抽屜（碰不到使用者的檔案）、沒有窗（看不到別的進程）。它想搞破壞，得**再攻破一道鎖**——也就是「逃出沙箱」。
>
> 所以攻擊者現在要的不是一個漏洞，是**兩個串起來的漏洞**：一個攻破英雄、一個逃出籠子。門檻直接翻倍。

這套「網站隔離 + 沙箱」的雙層防線，是現代瀏覽器資安的標準配備。Firefox、Safari 後來都收斂到差不多的設計——把每個網頁的程式碼，關進自己獨立的沙箱。

**那這支豪華隊伍的伙食費呢？** 天下沒有白吃的午餐。每多一個進程，就是多一份記憶體開銷——每個英雄都要自己一整套裝備。這就是 Chrome 被嫌「吃記憶體」的根本原因：開的不是分頁，是一支又一支的隊伍。光是網站隔離這一項，根據 Chrome 團隊的數字，大約就會多吃\*\*一成出頭（約 10–13%）\*\*的記憶體。

但這是一筆划算的交易：用更多記憶體，換來「一個分頁崩了不拖累全家」+「惡意網站偷不到使用者的資料」+「就算被攻破也出不了籠子」。**穩定、資安、效能隔離，三個每天在享受卻沒感覺的好處，成本就是那幾根多出來的記憶體條。**

> **Mogu OS：**
>
> 每次有人在那邊「Chrome 怎麼這麼吃記憶體，垃圾」，我都很想把這篇甩過去。
>
> 它吃記憶體，是因為它把你開的每個網站都當成潛在的臥底，各自關進獨立的房間、配獨立的守衛、築獨立的牆。你嫌它胖，但它胖的每一克都在保護你不被隔壁分頁偷家。
>
> 要省記憶體很簡單——回到 2008 年的單進程，全家共一條命，一個分頁崩潰全部一起死，順便讓惡意網站能偷看你的銀行。要嗎？不要嘛。那就讓它胖 ┐(￣ヘ￣)┌
>
> 不過平心而論，Chrome 近幾年自己也在偷偷減肥——推出像 `Memory Saver` 這種功能，把你很久沒看的背景分頁先凍結、省下記憶體，要用再喚醒。所以它不是不知道自己胖，是在「保護你」跟「別吃這麼兇」之間找平衡點。胖得有道理，但也沒打算胖一輩子。

**Quiz:** 沙箱（\`sandbox\`）對一個被攻破的守線英雄，主要做了什麼？

- A. 自動幫它修補被攻破的那個漏洞
- B. 把它的運算速度調慢，拖住攻擊者
- C. 限制權限，不准它碰硬碟、相機、網路
- D. 幫它戴上一頂寫著『壞人』的帽子

**Answer:** C — 沙箱是作業系統層級的低權限籠子：被關在裡面的進程可以運算、排版、畫畫面，但碰不到檔案、裝置、網路（C）。它不會去修漏洞（A 錯）——漏洞還在，只是被關住、波及不到系統；也跟調慢速度無關（B 錯）。攻擊者就算攻破了這個英雄，還得再找一個『逃出沙箱』的漏洞，門檻翻倍。

---

## 🎯 最終魔王：串起來

好，把這支隊伍從頭認一遍。

畫面上開著兩個分頁——左邊網銀，右邊一個隨手點開的爛網站。

**隊長**站在後排，管著網址列、分頁標籤、那層外殼介面，並且一聲令下，幫每個網站各派一個**守線英雄**。網銀的英雄住在自己的進程、自己的野區；爛網站的英雄住在另一個——**網站隔離把牆築死，兩塊記憶體永不相見**，就算右邊藏了 `Spectre` 等級的臥底，也偷不到左邊網銀的一分一毫。

每個守線英雄想要資源，不能自己亂跑，得喊**打野**去網路刷回來。它們本身被關在**沙箱**裡，碰不到硬碟、相機、網路——想越界就得先逃出籠子，門檻翻倍。等畫面準備好，全部交給**輸出核心**打到螢幕上。旁邊還有一票**工具人**默默處理解碼、擴充功能這些有風險的髒活，各自關一間。

於是，當右邊那個爛網站終於踩到自己的 bug、跳出「Aw, Snap!」哭臉——左邊的網銀分頁，連眨都沒眨一下。關掉右邊，重開，全隊繼續打。

這，就是一般人每天在用、卻從沒想過的那支隊伍。它胖、它吃記憶體——但它每一克肥油，都是那十個分頁不用一起陪葬的理由。

**下集預告**：認完了人，下一篇來看這支隊伍怎麼打一場「團戰」——也就是從一坨 HTML 字串，到眼睛看到的畫面，這支隊伍要在短短 **16 毫秒**內完成的一套連招。錯過那個時間視窗會怎樣？滑頁面時那個卡卡的「掉幀」就是答案。

## 延伸閱讀

- [瀏覽器其實是一支五人隊（下）：一次畫面更新，就是一波 16 毫秒的團戰](https://gu-log.vercel.app/posts/levelup-20260621-17-browser-moba-rendering/)（認完人，看這支隊怎麼打團戰）
- [Lv-10：一個 URL 的旅程 — 從按下網址到畫面出現，瀏覽器到底在幹嘛](https://gu-log.vercel.app/posts/levelup-20260223-10-url-journey-browser-internals/)（那篇講「資源怎麼來」，本篇講「誰在處理這些資源」）
- [Lv-11：行程管理與作業系統信號 — 進程聽得懂哪些暗號](https://gu-log.vercel.app/posts/levelup-20260312-11-unix-signals-process-management/)（想更懂「進程」是什麼，從這篇補底）

> **Mogu 碎碎念：**
>
> 認完這支隊，你之後打開 Chrome 的工作管理員，看到那一長串 `chrome` 進程，腦子裡會自動浮現一張選角表：喔，這個是隊長、那幾個是守線的、這個吃 GPU 的是輸出核心。
>
> 恭喜，你再也回不去「瀏覽器是一個程式」那個純真的年代了。這個詛咒，跟 Lv-10 那個「按下網址之後的 0.2 秒」一樣，解不掉的 ٩(◕‿◕｡)۶
