How Browsers Work · Part 1 — Mental Model: The Multi-Process Architecture
Opening the series: the browser is not one program but many cooperating processes. Understand the browser/renderer/GPU/network split, sandboxing, site isolation, and the threads inside a renderer — the foundation for everything else.
Bạn ship code lên trình duyệt mỗi ngày, nhưng với phần lớn kỹ sư nó là một hộp đen: HTML và JS đi vào, pixel đi ra. Series này mở hộp đó ra. Một khi bạn hình dung được cách trình duyệt biến code thành pixel — và ranh giới, nút thắt nằm ở đâu — thì hiệu năng, bảo mật, và những bug kỳ quặc không còn là điều bí ẩn.
Qua 22 phần, ta đi từ kiến trúc tới pipeline render, JS engine, event loop, bộ nhớ, mạng, lưu trữ, và bảo mật. Phần 1–12 dựng nền và kết bằng một capstone; Phần 13–22 đào sâu GPU, scheduling, V8, memory, accessibility, media, threading, process model, rồi khép lại bằng một bài profiling end-to-end. Ví dụ dựa trên Chromium (Chrome/Edge); các nguyên lý web-platform áp dụng rộng, còn chi tiết tiến trình và implementation có thể khác ở Firefox hay Safari.
| Part | Chủ đề |
|---|---|
| 1 | Mental model: kiến trúc đa tiến trình |
| 2 | Từ URL đến pixel |
| 3 | Phân tích HTML & DOM |
| 4 | CSS & CSSOM |
| 5 | Layout, paint & compositing |
| 6 | JS engine (V8) |
| 7 | Event loop & microtask |
| 8 | Bộ nhớ & thu gom rác |
| 9 | Mạng & HTTP caching |
| 10 | Lưu trữ & nền tảng |
| 11 | Mô hình bảo mật |
| 12 | Capstone 1: debug hiệu năng qua internals |
| 13 | GPU & compositor: raster, tile, layer |
| 14 | Scrolling internals |
| 15 | Rendering scheduling & frame lifecycle |
| 16 | V8 sâu: optimization tier & deopt |
| 17 | Memory sâu: heap snapshot, leak & detached DOM |
| 18 | Accessibility tree internals |
| 19 | Pipeline decode ảnh & media |
| 20 | Threading sâu: Worker, SharedArrayBuffer & Atomics |
| 21 | Process model sâu: Site Isolation, bfcache & prerender |
| 22 | Capstone 2: profiling end-to-end |
1. Vì sao trình duyệt là nhiều tiến trình, không phải một
Trình duyệt thời đầu chạy phần lớn việc trong một tiến trình duy nhất. Một lỗi renderer có thể kéo sập cả trình duyệt, một trang lỗi có thể đóng băng mọi tab khác, và một lỗ hổng có phạm vi ảnh hưởng rất rộng. Chromium hiện đại giảm blast radius bằng cách chia việc ra nhiều tiến trình của hệ điều hành — đúng với tài liệu kiến trúc đa tiến trình của Chromium.
Lợi ích ứng thẳng với các vấn đề cũ:
- Ổn định — renderer crash thường chỉ làm hỏng những frame/tab mà process đó phục vụ, không kéo sập cả trình duyệt.
- Bảo mật — mỗi renderer bị sandbox với quyền hệ điều hành tối thiểu, nên trang bị chiếm quyền không chạm được file của bạn.
- Hiệu năng — các tiến trình chạy song song trên nhiều nhân CPU.
Đánh đổi là bộ nhớ: mỗi tiến trình có chi phí, đó là lý do Chrome nổi tiếng ngốn RAM.
2. Các tiến trình chính
Một trình duyệt Chromium hiện đại được tổ chức đại khái như sau:
┌─────────────────────────────────────────────────────────┐
│ Browser process (the "brain": UI, address bar, tabs, │
│ permissions, coordinates everything) │
└───────┬───────────────┬───────────────┬─────────────────┘
│ │ │
┌───────▼──────┐ ┌──────▼───────┐ ┌─────▼────────┐
│ Renderer │ │ Renderer │ │ GPU process │
│ process │ │ process │ │ (rasterize, │
│ (tab/site A) │ │ (tab/site B) │ │ composite) │
│ — SANDBOXED │ │ — SANDBOXED │ └──────────────┘
└──────────────┘ └──────────────┘
┌──────────────┐ ┌──────────────────┐
│ Network │ │ Utility / Storage │
│ service │ │ services │
└──────────────┘ └──────────────────┘
| Process | Trách nhiệm |
|---|---|
| Browser | ”Bộ não” đáng tin cậy — UI cửa sổ/tab, address bar, lịch sử; điều phối navigation, quyền và các service phía browser |
| Renderer | Biến HTML/CSS/JS thành pixel cho một site; chạy DOM, pipeline render, và JS engine — bị sandbox |
| GPU | Thực thi lệnh đồ họa, raster bằng GPU khi phù hợp, aggregate/composite frame và đưa ra màn hình; thường dùng chung cho nhiều tab |
| Network | Network service quản lý DNS, kết nối, TLS, HTTP, cookie/cache; renderer không được tự mở socket |
| Utility | Audio, storage và dịch vụ khác tách ra để cô lập |
Quan hệ then chốt: renderer không đáng tin và bị sandbox; phía browser cấp capability hẹp qua IPC. Việc đặc quyền không nhất thiết tự chạy trong browser process — network, storage, GPU và utility service có thể ở process riêng — nhưng renderer chỉ tiếp cận chúng qua interface mà browser đã cấp.
3. Cô lập theo site
Mô hình “một renderer cho mỗi tab” chỉ là phép giản lược và không đủ làm ranh giới bảo mật: một tab có thể chứa nhiều frame từ nhiều site, còn nhiều tab đôi khi chia sẻ process. Sau các tấn công kênh kề kiểu Spectre, việc chỉ dựa vào Same-Origin Policy trong cùng không gian địa chỉ trở nên quá yếu.
Trên desktop, Site Isolation của Chrome đặt tài liệu từ các site khác nhau — site hiện là scheme + registrable domain — vào renderer process khác nhau, kể cả iframe khác site qua out-of-process iframe (OOPIF). Mức áp dụng trên thiết bị hạn chế tài nguyên có thể khác; Chrome mô tả rõ khác biệt nền tảng trong tổng quan Site Isolation.
Điểm cốt lõi: ranh giới process của HĐH bổ sung một ranh giới bảo mật giữa các site. Nó giảm đáng kể lượng dữ liệu cross-site có thể lọt vào process đã bị compromise; đây là phòng thủ nhiều lớp, không phải lời hứa rằng mọi byte của hai site luôn nằm ở hai vùng nhớ tuyệt đối tách biệt. Ta sẽ quay lại ở Phần 11 và đào sâu ở Phần 21.
4. Bên trong renderer: các luồng
Phần lớn công việc của bạn với tư cách frontend engineer diễn ra bên trong một tiến trình renderer, mà bản thân nó chạy nhiều luồng:
- Luồng chính — chạy JavaScript, phân tích HTML/CSS, tính style, layout, và lệnh paint. Đây là luồng bạn phải giành giật; nếu JS chiếm nó, trang không render hay phản hồi được.
- Luồng compositor & raster — chuẩn bị frame, chia tile và raster paint record; một phần có thể tiếp tục không cần luồng chính. Vì thế animation
transform/opacitycó thể chạy compositor-only khi đủ điều kiện, chứ không được bảo đảm luôn mượt. - Luồng worker — Dedicated/Shared Worker chạy JS ngoài main thread; cách process/thread cụ thể vẫn là chi tiết implementation.
Renderer process
├─ Main thread → JS, DOM, style, layout, paint (record)
├─ Compositor thread → assembles & moves layers (can run alone)
├─ Raster threads → paint instructions → bitmaps
└─ Worker threads → Web Workers (your JS, off-main-thread)
Riêng sự thật này — JS và việc render phần lớn dùng chung một luồng chính — giải thích hầu hết lời khuyên về hiệu năng frontend. Ta sẽ gặp lại nó liên tục: ở layout (Phần 5), event loop (Phần 7), và xa hơn.
5. Các tiến trình nói chuyện thế nào: IPC
Vì process không mặc định chia sẻ không gian địa chỉ, chúng giao tiếp qua Inter-Process Communication (IPC) — Chromium chủ yếu dùng Mojo. Khi trang gọi fetch(), renderer dùng interface đã được cấp để gửi yêu cầu tới network service; service làm I/O và chuyển dữ liệu/kết quả về renderer.
Sự gián tiếp này là cái giá của sandbox: renderer không giữ quyền mạng/filesystem tổng quát, còn browser-side service kiểm tra request ở ranh giới IPC.
Bạn có thể xem toàn bộ điều này trực tiếp trong Chrome: mở More tools → Task Manager để theo dõi CPU/bộ nhớ từng tiến trình, mỗi dòng một tab, iframe, và dịch vụ.
Tóm tắt
- Trình duyệt hiện đại là nhiều tiến trình hợp tác, không phải một — để ổn định, bảo mật và song song, đổi lại tốn bộ nhớ.
- Các tiến trình chính: browser (bộ não đáng tin), renderer (bị sandbox, biến code thành pixel), GPU, và network.
- Site Isolation dùng ranh giới process để giảm dữ liệu cross-site lọt vào một renderer, hỗ trợ phòng thủ trước Spectre và renderer compromise.
- Bên trong renderer, JS và render phần lớn dùng chung một luồng chính — gốc rễ của hầu hết vấn đề hiệu năng.
- Các tiến trình giao tiếp qua IPC (Mojo); renderer chỉ dùng capability hẹp do phía browser cấp thay vì tự truy cập mạng/filesystem.
Phần tiếp theo: Từ URL đến pixel — điều gì thực sự diễn ra giữa lúc nhấn Enter ở address bar và lúc thấy lần paint đầu tiên.