第二版 · 2026-07-26 · 66 筆原始資料 · 宣告 4x CPU throttle

前端效能病理標本館

66

每個數字量三次。
對不上的時候,改的是實驗,不是結論。

六個效能反模式,每個做成一組病變版與一到三段治療版,其他變因全部凍結。 22 個對照臂各跑三輪,判定離散度與兇手是否一致。 這一頁列出的每個比值都能在公開的原始資料裡覆算。

6核心標本
22對照臂
3輪/每臂
30%離散度判準
0.0%本輪最佳離散度

這是一份實驗,不是一個應用程式

每個標本頁展示一個效能反模式,可以即時切換病變版與治療版,旁邊的面板顯示實測指標。 產出物是一句話:其他條件全部凍結時,翻動這一個變因,產生這個差距。

追求可重現,不追求絕對精確。 判準只有一條:這個誤差會不會翻轉結論?會就修,不會就標註然後繼續。 解析度下限直接印在面板上 —— 例如 duration 是 8ms 量化的, 小於那個網格的差距一律不宣稱。

環境變因不是要解決的,是要凍結並宣告的。 viewport 凍在 800×600、種子固定、build 保留函式名讓證據能指出兇手函式。 CPU throttling 無法從 JavaScript 偵測,所以它是宣告不是偵測 —— 沒有宣告的截圖等同作廢。

標本索引

比值取自 2026-07-26 那一輪的三輪 median。標記 △ 的臂在本輪沒有通過可重現判準,數字列出來但不採信 —— 留在原地比刪掉誠實。

病變 → 最佳治療臂。完整的每一臂數字在原始資料 JSON 裡。
標本 主指標 病變 → 治療 比值 本輪判定
01 主執行緒阻塞 在事件處理器裡同步排序五萬筆訂單 INP median 952 → 24 ms 39.7× 治療臂落在 8ms 量化底噪(24/48/20);兇手屬交界標本
02 長列表未虛擬化 一次渲染 5000 筆,約 40,000 個 DOM 節點 LCP 2012 → 100 ms 20.1× 三臂皆可重現,病變離散度 14.1%
03 強制同步版面重排 迴圈裡交替讀寫版面屬性,800 列就是 800 次 forced style & layout 731 ms → 三輪零幀 治療版無 entry,不報比值 病變離散度 1.7%
04 事件處理未節流 scroll handler 每次事件掃過 8000 列 掉幀峰值 99 → 10 幀 9.9× passive 臂反而優於病變 7~8 幀 —— 判準落空,照實記
05 版面位移 圖片沒尺寸、字族換入、延遲插入橫幅 CLS 0.2474 → 0(無 entry) 三段梯度 2.4× / 2.8× / 歸零 四臂離散度 0.0%,病變值命中解析值 0.247426
06 re-render 風暴 每 25ms 推一批,病變版每批重建整張 1000 列清單 有渲染的幀距 median 167 → 16.7 ms 10.0× 主指標離散度 2.6%;判準雙絕對錨首次生效,通過

三條規矩,違反就重做

  1. 動工前先登記預期

    每個標本在寫第一行程式之前,先把預期的量級、兇手段與判準寫進登記文件。 登記完就不准回頭改去迎合實測 —— 要改就在檔尾追加修正紀錄,寫明改了什麼、為什麼、 作廢了哪些既有數字。沒有預期,「這個誤差會不會翻轉結論」這條判準是空的。

  2. 一段治療只准翻一個變因

    順手多改一件事,殘差就歸因不到那個變因,那段治療的數字作廢。 這是本站踩過最多次的坑:曾經有一段治療宣稱「只把事件改成 passive」, 實際上同時抽掉了一整輪八千次的版面讀取。

  3. 修變因,不修結論

    量到不符預期,改的是實驗設計,不是把結論改成符合實測。 已經發出去的文章不回頭改數字 —— 那是有日期、附原始資料的快照, 後續發現問題就寫下一篇。

這一輪有哪些數字不能用

這一節不是免責聲明,是資料的一部分。一份只列成功案例的量測,讀者沒有辦法判斷它可不可信。

標本 #2 判定為不可重現,而它這一輪一個字都沒改

病變版離散度 34.0%、其中一段治療 110.7%(三輪之一掉到 204ms)。 疑似載入期指標在多 mode 輪替下的取樣問題,尚未查清 —— 所以本輪的 #2 數字不拿去發表。

跨 session 的絕對值不可比,只有同一份資料內部的比值可比

標本 #3 這一輪也沒有改動,主指標卻從上一輪的 745 / 716 / 678 ms 變成 1158 / 1274 / 1376 ms —— 約兩倍,而它自己三輪的離散度只有 17.1%。同一台機器、同一天、相隔數小時。 所以本站的可比較單位是「同一份原始資料內部的臂間比值」,不是跨檔案的絕對毫秒數。

一個登記在案的兇手,被自己的資料推翻

標本 #1 登記的兇手是 input delay,三輪實測一致是 presentation —— 而「三輪兇手一致」這條判準當時判它通過,因為它只檢查三輪彼此一致,沒有檢查是否等於登記值。 後來才想清楚這是結構性的:同步阻塞的處理器讓十次點擊共用同一次繪製, 代表樣本恆為第一發,而第一發前面沒有隊可排。登記值已改判並寫進修正紀錄。

4x CPU 節流套不到 worker 執行緒

節流器掛在算繪程序的主執行緒上,dedicated worker 是獨立目標。 證據在資料裡:同一份工作主執行緒 116~122ms、worker 28.4~29.0ms,比值 4.2 恰好等於節流率。 這是一個對治療臂有利的混淆變因,已登記成明文例外,而不是留在心裡。

要自己覆算?先把 throttle 打開

沒有節流的話,現代開發機會把大部分病變吃掉 —— 你會看到一個「好像也還好」的數字, 然後得出錯誤的結論。本站所有登記的預期值都綁在 4x 這個宣告上。

開啟方式。 開 DevTools → Performance 面板 → 齒輪 → CPU → 選 4× slowdown。 接著回到本站面板的下拉選單,把 4x 這件事宣告一次 —— JavaScript 偵測不到節流倍率,面板只能記下你說的話。沒宣告的數字不進帳。

還有兩件事會讓數字不算數。 量測一律走產物版本,不要在開發伺服器上量(不 minify、不打包、帶熱更新開銷, 量到的跟產物是兩回事;開發模式下面板頂端會有紅字提醒)。 另外需要 Chromium 系瀏覽器 —— 互動編號與長動畫幀都是 Chromium 才有, 這是明文宣告的限制,不做跨瀏覽器降級。