
你遇到的大多數效能問題,根源都在瀏覽器的底層機制裡。
先講結論
「我是前端工程師,幹嘛要了解瀏覽器怎麼運作?」——因為你遇到的頁面卡頓、動畫不流暢、JS 阻塞畫面,全部都跟瀏覽器的底層機制有關。搞懂它,你才知道為什麼 transform 比 top/left 效能好、為什麼 setTimeout(fn, 0) 不是真的零延遲、為什麼一個分頁掛了不會拖垮其他分頁。
多進程架構:每個分頁都是獨立公民
Chrome 的架構簡單說就是:一個老大(Browser Process)管所有小弟(Renderer Process)。
Browser Process 管 UI、網路、儲存——就是瀏覽器本身的框框。每個 Tab 有自己獨立的 Renderer Process 負責渲染網頁。還有 GPU Process 專門處理圖形運算。
這就是為什麼一個分頁掛了,其他分頁還活得好好的。每個分頁是獨立的進程,互不干擾。代價是記憶體用量比較大——打開 Chrome 工作管理員看看,你就知道為什麼 Chrome 是記憶體怪獸了。
Renderer Process:前端的戰場
每個渲染進程有三個重要的執行緒:
主執行緒(Main Thread) 負責解析 HTML/CSS、執行 JavaScript、計算佈局。注意——這是單執行緒。你的 JS 跟渲染搶同一條路,這就是為什麼跑一段很重的 JS 會讓畫面卡住。
合成執行緒(Compositor Thread) 處理圖層合成跟滾動。transform 和 opacity 的動畫不需要經過主執行緒,直接在合成執行緒處理,所以效能特別好。
光柵化執行緒(Raster Thread) 把向量圖形轉成像素。
V8 引擎:JS 的加速器
Chrome 的 V8 引擎把你的 JavaScript 從文字變成機器碼,大致流程是:原始碼 → Parser 解析成 AST → Ignition 解譯器產生 Bytecode → TurboFan JIT 編譯器把熱點程式碼優化成機器碼。
記憶體方面,Stack 放基本類型跟函數呼叫,Heap 放物件跟陣列,垃圾回收會自動清理不用的記憶體。你不需要手動管記憶體,但你要知道什麼時候會造成 memory leak——比如忘了清掉的 event listener 或不斷增長的陣列。
事件循環:單執行緒的生存之道
JavaScript 明明是單執行緒,怎麼處理非同步操作?靠事件循環(Event Loop)。
執行順序是這樣的:先跑完同步程式碼 → 清空 Microtask Queue(Promise.then) → 執行一個 Macrotask(setTimeout) → 重複。
console.log('1'); // 同步
setTimeout(() => {
console.log('2'); // Macrotask
}, 0);
Promise.resolve().then(() => {
console.log('3'); // Microtask
});
console.log('4'); // 同步
// 輸出:1, 4, 3, 2面試超愛考這個。但更重要的是,搞懂這個你才知道為什麼 setTimeout(fn, 0) 不是立即執行——它只是被丟到 Macrotask Queue 排隊等前面的事情做完。
渲染管線與效能
JavaScript → Style → Layout → Paint → Composite
改幾何屬性(寬高、位置)會觸發重排(Reflow),整條管線重跑一次,效能衝擊最大。改外觀(顏色、背景)觸發重繪(Repaint),跳過 Layout。用 transform 跟 opacity 只走合成(Composite),效能最好。
// ❌ 觸發重排
element.style.left = '10px';
// ✅ 只走合成,效能好很多
element.style.transform = 'translateX(10px)';這不是什麼微優化潔癖,當你有大量動畫或清單渲染時,差距是肉眼可見的。
瀏覽器每秒幫你做了幾百萬件事,理解它的辛苦,你才會寫出它跑得動的程式碼。
延伸閱讀
Inside look at modern web browser JavaScript Visualized: Event Loop 瀏覽器發出request後經歷了什麼 JavaScript