Core Web Vitals:用 LCP、FID、CLS 量網頁效能,並用工具找出該修的地方

文字解析 · 1 支影片 · 產生於 2026-10-01 00:54

🎧 語音解析📝 筆記✍️ 練習

🎧 語音解析 15m02s · TTS 講解與作者原聲交錯;點章節可跳。
邊聽邊看逐句講稿,點任一句從那裡開始
章節(7)

1. Outline

  1. 起點 · The ultimate guide to web performance
    把「網站要快」換算成商業損失,再收束成三個可量測的指標(LCP/FID/CLS),依序給定義、門檻與優化手段,最後用 Web Vitals 擴充套件做單頁診斷、用 Unlighthouse 掃全站,並拿 Amazon、Google、astro.build 的實測分數當證據。

2. YouTuber 的思維推導

The ultimate guide to web performance

Beyond Fireship · 6m43s · 字幕 en · vision=on (使用者指定 vision=true;影片大量以畫面示範 network waterfall、擴充套件的 console log 與 Unlighthouse 儀表板,讀圖能對應說明。) · YouTube

預估 vs 實際耗時
階段預估實際
fetch 6s 1s
segment 43s 5m00s
shot 23s 3s
analyze 3m45s 9m00s
render 5s –

作者從一個非技術的前提出發:現代人注意力極短,網站慢就會讓人跳走、直接等於少賺錢。於是他把「效能」這個模糊的話題,換算成商業損失,再收束成三個可量測的指標。接著他刻意用同一套模板依序推導三個指標——先問「這個指標在量什麼」,再給 Google 的好/壞門檻數字,最後給對應的優化手段:LCP 量載入(壓資源、上 CDN、避開 render blocking JavaScript、調資源優先權),FID 量互動(唯一解是減少 JavaScript 執行時間),CLS 量視覺穩定(給圖片尺寸、用 aspect-ratio)。

三個指標講完後,他轉了一個彎:知道指標還不夠,你得能量到自己的網站。於是先用 Web Vitals 擴充套件示範單頁診斷——它的價值在於直接指出「是哪一個 DOM 元素害的」;再指出單頁工具在幾百上千頁的網站上不管用,帶出 Unlighthouse 這個平行掃全站的開源工具。最後他不用自己的意見收尾,而是拿 Amazon、Google、Reddit、GitHub、astro.build 的實測分數當證據,讓「照這些原則做真的有差」由數字自己說話,並以「有 SDK 可接進 CI」把一次性的檢查變成可持續的流程。

推理鏈:每段留給下一段的線索

每一列是一段,箭頭後的字是這段留給下一段的線索。點段落標題跳到該段。

  1. 為什麼要在意初次載入效能 → 三個指標被點名了,但都還只是名字。第一個要拆開的是量「載入」的那一個:largest contentful paint 到底從什麼時候算到什麼時候,多少秒才算好?
  2. LCP:載入效能怎麼量 → 現在知道 LCP 是什麼、也知道怎麼在瀑布圖上認出瓶頸了。但認出瓶頸不等於解決它——找到那條特別寬的線之後,實際上有哪些手段可以把它變短?
  3. 優化 LCP 的三層做法 → 到這裡「怎麼讓畫面早點出現」已經有一整套答案了。但作者在段末丟下一句話:LCP 不是唯一要擔心的事。畫面出現了,使用者伸手去點卻按不動,那又是哪一個指標在量?
  4. FID:畫得出來還要按得動 → 載入與互動都有指標了,但還有一種糟糕體驗不屬於這兩者:東西看得到也按得動,卻在你手指按下去的瞬間自己跳走位置。這種「畫面亂跳」要用第三個指標來量。
  5. CLS:畫面不能亂跳 → 三個指標到這裡全部講完,讀者手上有了完整的量測語言。但這些都還是紙上的定義——真正的問題是:怎麼在自己的網站上實際量到這些數字,而且知道是「哪一個元素」害的?
  6. Web Vitals 擴充套件:單頁診斷 → 這個工具能把單一頁面的問題釘到具體元素,但作者立刻點出它的天花板:一次只能看一頁。網站有幾百甚至幾千頁時,人不可能一頁一頁開——那就需要一個能一次掃完整站的工具。
  7. Unlighthouse:整站掃描與實測

3. 逐段說明

The ultimate guide to web performance

1. 為什麼要在意初次載入效能 0:00–0:46

作者用「五秒抓不住你就跳走」當開場,指出現代人注意力極短,網站慢就等於少賺錢。於是把問題收束成三個要懂的指標:largest contentful paint、first input delay、cumulative layout shift。並預告不只講 Lighthouse,還會用 Web Vitals 擴充套件與 Unlighthouse 去實測 Amazon、Google 等真實網站。

承上 承接前情提要裡「這是一支給網頁開發者的效能速成影片」這個背景:作者不假設你懂任何指標,而是先建立一個你一定在意的動機——使用者的注意力,以及背後的錢。

推理作者一開場就把自己當實驗品:「如果我不能在接下來五秒抓住你,你就不會看完」。因為他要讓你先接受「注意力是稀缺資源」這個前提,所以才能推出下一步——網站慢=使用者跳走=少賺錢。有了這個商業動機,他才有立場說「achieving Optimal Performance is complex」,並把複雜度收束成三個具體名詞:largest contentful paint、first input delay、cumulative layout shift。最後他預告工具(Web Vitals 擴充套件、Unlighthouse)與實測對象(Amazon、Google),但立刻煞車:「要把這些工具用好,得先搞懂 core web vitals」——先建立量測的語言,再拿工具。

AI 補充作者說「網站慢就會少賺錢」時跳過了中間那一步:慢到什麼程度、掉多少?補上這一步會讓後面的門檻數字有意義——Google 與各家零售商的公開研究長期給出的量級大致是「載入時間每多一秒,轉換率掉個位數百分比」,而 Core Web Vitals 之所以被訂成三個而不是十個,正是因為 Google 挑的是「與跳出率相關性最高、且開發者改得動」的三件事。另外要先建立一個貫穿全片的分工:這三個指標不是隨機湊的,而是把「使用者感受」拆成三個互不重疊的面向——看得到(載入)、按得動(互動)、不亂跳(穩定)。作者接下來每講一個指標,其實都是在填這三格的其中一格;先知道有這張表,後面三段就不會覺得是三個零散的知識點。

Core Web Vitals

核心網頁指標

Google 訂出的一小組使用者體驗指標,用來量網頁「載入、互動、視覺穩定」三個面向。

Core Web Vitals 是 Google 從 2020 年開始推的一套標準,重點在於它刻意只有三個:多了開發者記不住,少了又蓋不住體驗。它同時是搜尋排名的訊號之一,所以不只是工程議題,也是行銷議題。常見誤解是把它跟 Lighthouse 分數混為一談——Core Web Vitals 是指標本身,Lighthouse 只是量它的其中一種工具,而且是在你自己機器上模擬出來的實驗室數據。真正拿來排名的是真實使用者的欄位資料(CrUX)。這組指標的成員會改版:影片拍攝時是 LCP/FID/CLS。

相關術語: Lighthouse (量測工具之一)

出處:第 1 段「為什麼要在意初次載入效能」

Lighthouse

Lighthouse 效能稽核工具

Google 內建在 Chrome DevTools 的網頁稽核工具,跑一次會給效能、無障礙、最佳實務、SEO 四個分數。

Lighthouse 是模擬環境下的實驗室測試:它會用固定的 CPU 降速與網路節流跑一次頁面,所以同一頁在不同機器上分數會抖動。它的效能分數是多個指標的加權平均,不等於任何單一的 Core Web Vitals 指標。作者說「我講的不只是 Lighthouse」,意思是 Lighthouse 一次只看一頁、而且是模擬值,實務上還需要真實使用者資料與整站掃描。它也是後面那個整站工具的底層引擎。

相關術語: Core Web Vitals (量它的工具)

出處:第 1 段「為什麼要在意初次載入效能」

bounce

跳出

使用者一進站沒有任何進一步互動就離開,是效能變差時最先惡化的商業數字。

跳出率之所以被拿來當效能的代理指標,是因為它是少數能直接連到營收的行為數據:使用者不會填問卷說「你網站太慢」,他們只會關掉分頁。效能與跳出率的關係不是線性的,通常在幾個心理門檻(約 1 秒、3 秒)附近會斷崖式惡化,這也是為什麼 Google 的指標門檻都訂在這種整數秒附近。要注意跳出率高不一定是效能問題,也可能是內容不對;效能只是它其中一個可控的成因。

相關術語: Core Web Vitals (想改善的目標)

出處:第 1 段「為什麼要在意初次載入效能」

留給下一段 三個指標被點名了,但都還只是名字。第一個要拆開的是量「載入」的那一個:largest contentful paint 到底從什麼時候算到什麼時候,多少秒才算好?

2. LCP:載入效能怎麼量 0:46–1:28

largest contentful paint 量的是載入效能:網頁先出現 first contentful paint,接著逐步載完圖片影片,最大那塊內容畫出來的時間就是 LCP。Google 的門檻是 2.5 秒內算好、超過 4 秒算差且會影響 SEO。最基本的分析方式是打開瀏覽器 network 分頁看瀑布圖,特別寬的那一條就是瓶頸。

作者說瓶頸「在圖上會是特別寬的一條」——network waterfall 的形狀要看到圖才能理解怎麼認瓶頸。
1:24 · 作者說瓶頸「在圖上會是特別寬的一條」——network waterfall 的形狀要看到圖才能理解怎麼認瓶頸。
承上 承上:上一段留下的問題是「largest contentful paint 從什麼時候算到什麼時候、多少秒才算好」。這一段就把這個量「載入」的指標從定義、門檻到診斷方法一次補完。

推理因為上一段已經確立「使用者在意的是多快看得到東西」,所以作者接著要找一個能代表這件事的時間點。他的推導是:網頁載入其實是一連串資源抓取(CSS、HTML、JavaScript、圖片、影片),中間會先出現 first contentful paint,然後畫面才逐步長齊——所以最能代表「我看到這一頁了」的時刻,是最大那塊內容畫完的瞬間,這就是 LCP。有了定義才能談門檻:2.5 秒內算好、超過 4 秒算差,而且會影響 SEO(這一句把技術指標接回第 1 段的商業動機)。有了門檻才需要診斷方法,所以他最後落到最基本的一招:打開 network 分頁看瀑布圖,找特別寬的那一條。

AI 補充作者說「瓶頸在圖上會是特別寬的那一條」,但沒說怎麼讀寬度。截圖裡是 Amazon 商品頁在行動裝置模擬(375×667)下的 network 面板:333 個請求、28.7 MB 資源、DOMContentLoaded 2.83 秒、整頁 Finish 12.86 秒。值得注意的是,畫面上大多數條目是 479 B 的 gif 與 ping(廣告與追蹤的 beacon),它們每個都很快,卻靠數量把連線數吃光——這說明「寬」有兩種:一種是單一資源真的很大(一條長綠條),一種是它前面排了太多東西,等待時間被拉長。DevTools 的瀑布圖裡淺色段是排隊與等待、深色段才是實際傳輸,這個區分決定你該壓縮檔案還是該減少請求數。另外一個作者省略的關鍵:LCP 元素通常就是首屏那張最大的圖或那段標題文字,找到它比看整張瀑布圖更快——而這正是作者稍後要介紹的診斷工具要解決的事。

術語:Largest Contentful Paint (LCP)First Contentful Paint (FCP)network waterfallSearch Engine Optimization (SEO)

Largest Contentful Paint (LCP)

最大內容繪製

從開始載入到視窗內「最大那塊內容」(通常是主圖或大標題)畫出來所花的時間,代表載入效能。

LCP 取代的是更早的 load 事件與 first meaningful paint:load 太晚(連追蹤碼都算進去),而使用者其實在主圖出現時就覺得「載好了」。它只看視窗內(above the fold)的元素,而且會隨著頁面長齊不斷更新候選元素,直到使用者第一次互動才定案——所以同一頁在不同螢幕尺寸下,LCP 元素可能不一樣。門檻是 2.5 秒(好)/4 秒(差),而且判定用的是真實使用者的第 75 百分位,不是你自己電腦上跑出來的那一次。

相關術語: First Contentful Paint (FCP) (更早的前一個階段)、network waterfall (診斷用的圖)

出處:第 2 段「LCP:載入效能怎麼量」

First Contentful Paint (FCP)

首次內容繪製

畫面上出現第一個文字或圖片的時間點,代表「有東西了」而不是「載好了」。

FCP 是 LCP 的前一站:它只保證使用者不再盯著白畫面,內容可能只是一行標題或一個 spinner。兩者的差距很有診斷價值——FCP 快但 LCP 慢,通常代表 HTML 到得很快、但主圖或主要內容被 JavaScript 或大檔案卡住;兩者都慢則問題多半在伺服器回應或網路本身。FCP 不屬於 Core Web Vitals,但會算進 Lighthouse 的效能分數。

相關術語: Largest Contentful Paint (LCP) (之後才發生)

出處:第 2 段「LCP:載入效能怎麼量」

network waterfall

網路瀑布圖

瀏覽器開發者工具裡把每個資源的開始時間與持續時間畫成橫條、依序疊起來的圖。

瀑布圖之所以叫瀑布,是因為資源之間常有依賴:HTML 到了才知道要抓哪支 CSS,CSS 解析完才知道要抓哪個字型,於是條目一階一階往右下掉。看瀑布圖有三個切入點:階梯有幾層(依賴鏈太深)、哪條特別長(單一資源太大或伺服器太慢)、以及同一時間擠了多少條(請求數太多、連線被排隊)。每條橫條內部還會分成排隊、等待回應、實際下載三段,顏色不同,決定你該優化的是伺服器、網路還是檔案大小。

相關術語: Largest Contentful Paint (LCP) (用來找它的瓶頸)

出處:第 2 段「LCP:載入效能怎麼量」

Search Engine Optimization (SEO)

搜尋引擎最佳化

讓網頁在搜尋結果中排得更前面的一整套做法;Core Web Vitals 是其中的排名訊號之一。

把效能接到 SEO 是這支影片最重要的說服點:效能從「工程師的潔癖」變成「行銷部門也要在意的事」。實務上要注意權重——Google 官方說法是 Core Web Vitals 屬於「頁面體驗」訊號,在內容相關性面前是次要的加分項,兩篇內容相當時才會拉開差距。所以不要期待把 LCP 從 3 秒調到 2 秒就會讓排名跳升;它的真正回報通常先出現在跳出率與轉換率上。

相關術語: bounce (同一個商業動機)

出處:第 2 段「LCP:載入效能怎麼量」

留給下一段 現在知道 LCP 是什麼、也知道怎麼在瀑布圖上認出瓶頸了。但認出瓶頸不等於解決它——找到那條特別寬的線之後,實際上有哪些手段可以把它變短?

3. 優化 LCP 的三層做法 1:28–2:40

找到瓶頸後,作者給出三層優化:先減少資源載入時間(壓縮圖片、改用 webp、字型只留最低限度),上線後用 CDN 送資源(Firebase、Vercel 會自動處理),再來是避免 render blocking JavaScript——這正是 Next.js 這類伺服器端框架勝過純 React 單頁應用的理由。最後是現代瀏覽器的資源優先權:用 preload 讓重要資源先被發現,用 fetch priority 把頁尾的次要圖片降級。

preload link 與 fetchpriority 的實際寫法只在畫面上出現,聽聲音不知道屬性名怎麼寫。
2:28 · preload link 與 fetchpriority 的實際寫法只在畫面上出現,聽聲音不知道屬性名怎麼寫。
承上 承上:上一段停在「認出瓶頸之後呢」。作者這一段就正面回答,而且刻意由淺入深排出優化的順序。

推理因為上一段的診斷方法會指向「某個資源花太久」,所以作者接著的第一招最直觀:資源本身變小——壓縮圖片、改用 webp、字型只留最低限度。但檔案再小也得跨越距離,所以第二招是把資源放到離使用者近的地方,也就是 CDN(他順手指出部署到 Firebase 或 Vercel 會自動處理,降低心理門檻)。前兩招處理的是「東西多久到得了」,第三招處理的是「東西到了為什麼還畫不出來」——render blocking JavaScript:如果得先跑一段 JS 才顯示圖片,LCP 就被綁架。這一步他順勢把架構選擇也拉進來:Next.js 這類伺服器端框架比純 React 單頁應用受青睞,正是因為 SPA 初次載入得先跑一堆 JavaScript 才畫得出主要內容。最後一招是最細的:既然資源會互相排隊(第 2 段瀑布圖已經看過),那就用 preload 讓重要資源提早被發現,用 fetch priority 把頁尾的次要圖片降級。整段的推導軸線是同一個問題被問了三次:小一點、近一點、早一點。

AI 補充作者念出了 preload 和 fetch priority,但屬性怎麼寫只出現在畫面上。截圖裡的寫法是 `<link rel="preload" href="style.css" as="style" />`、`as="script"`、`as="video" type="video/mp4"`——這裡的 `as` 不是可省略的裝飾,少了它瀏覽器不知道該用什麼優先權去抓,還可能重複下載一次,等於白做。這是作者跳過的一步。另外兩個容易踩的坑:preload 是「提早發現」不是「提早畫出」,濫用會讓所有東西都變高優先權,等於沒有優先權;而 LCP 那張主圖其實不用 preload,用 `fetchpriority="high"` 寫在 `<img>` 上更直接。至於 render blocking,作者只講了 JavaScript,但預設情況下 CSS 才是最典型的 render blocking 資源——瀏覽器沒解析完 CSSOM 就不會畫任何東西,所以「把關鍵 CSS 內嵌、其餘非同步載入」通常比動 JavaScript 更快見效。

術語:Content Delivery Network (CDN)

WebP

WebP 圖片格式

Google 推出的圖片格式,同樣畫質下檔案通常比 JPEG/PNG 小 25–35%。

WebP 同時支援有損與無損壓縮,也支援透明與動畫,所以能一口氣取代 JPEG、PNG 和 GIF 三種用途。實務上不需要二選一:用 `<picture>` 搭配多個 `<source>`,讓支援的瀏覽器拿 WebP、不支援的退回 JPEG。要注意的是換格式只解決「檔案大小」,沒有解決「尺寸過大」——把一張 4000px 寬的圖轉成 WebP 再縮到 400px 顯示,仍然是浪費,該做的是先產出對應尺寸的版本。

相關術語: Largest Contentful Paint (LCP) (想縮短的目標)

出處:第 3 段「優化 LCP 的三層做法」

Content Delivery Network (CDN)

內容傳遞網路

把靜態資源複製到世界各地的節點,讓使用者從離自己最近的機器拿檔案的服務。

CDN 主要縮短的是往返延遲:檔案再小,如果每次來回都要跨太平洋,光是建立連線就先花掉幾百毫秒。它同時帶來三個附加好處——邊緣快取讓來源伺服器壓力大減、節點通常自動開啟壓縮與新版 HTTP 協定、以及吸收突發流量。作者說 Firebase 或 Vercel「會自動幫你處理」,指的是這類平台預設就把靜態產物推上自家 CDN,你不用自己設快取標頭。要注意動態內容(每個使用者不同的頁面)不能單純快取,需要邊緣運算或分層快取策略。

相關術語: network waterfall (縮短其中的等待)

出處:第 3 段「優化 LCP 的三層做法」

render blocking JavaScript

阻擋渲染的 JavaScript

必須先下載並執行完、瀏覽器才能繼續解析或繪製頁面的 JavaScript。

HTML 解析器碰到一支沒有標記的 `<script>` 就會停下來,因為那支腳本有可能用 `document.write` 改動後面的內容。解法是 `defer`(下載不擋解析,等 HTML 解析完才依序執行)或 `async`(下載不擋、下載完立刻執行、順序不保證);需要保持順序的應用程式碼用 `defer`,獨立的第三方腳本才用 `async`。更隱蔽的一種是「畫面內容本身要靠 JS 產生」——這時腳本不只擋解析,還讓 LCP 元素根本不存在於初始 HTML 裡,這正是單頁應用初次載入慢的根因。

相關術語: Single Page Application (SPA) (最常見的受害者)、Largest Contentful Paint (LCP) (會被它拖慢)

出處:第 3 段「優化 LCP 的三層做法」

Single Page Application (SPA)

單頁應用

只送出一份幾乎空白的 HTML,靠瀏覽器端 JavaScript 產生所有畫面與換頁的網站架構。

SPA 的優勢在換頁:第一次載入之後,之後的導覽不必重新要一份 HTML,體感像原生 App。代價全部押在第一次——瀏覽器要先下載框架與應用程式碼、執行、要資料、再渲染,這幾步全部落在 LCP 之前。所以 SPA 的效能特徵很典型:首次載入差、後續互動好。伺服器端渲染(SSR)與靜態產生(SSG)就是把第一步搬回伺服器,讓使用者拿到的第一份 HTML 就已經有內容,再由 JavaScript 接手(hydration)。

相關術語: render blocking JavaScript (初次載入的成因)

出處:第 3 段「優化 LCP 的三層做法」

preload

資源預載

用 `<link rel="preload">` 告訴瀏覽器「這個資源等一下一定會用到,現在就去抓」。

preload 解決的是「發現太晚」:有些資源藏在 CSS 或 JS 裡(例如 `@font-face` 指向的字型檔),瀏覽器要解析完才知道要抓,於是白白晚了一個往返。preload 把它提前到 HTML 掃描階段就被發現。必須寫 `as` 指出資源類型,瀏覽器才知道用什麼優先權、套什麼 CSP 規則;跨網域的字型還要加 `crossorigin`,否則會抓兩次。它是稀缺資源:預載三五個關鍵項目有效,預載二十個等於沒排序。注意它只提前「下載」,不會提前「執行」或「繪製」。

相關術語: fetch priority (同類的優先權工具)

出處:第 3 段「優化 LCP 的三層做法」

fetch priority

抓取優先權

寫在 `<img>`、`<script>`、`<link>` 上的 `fetchpriority="high|low|auto"`,用來提升或降低該資源的下載順位。

瀏覽器本來就有一套內建的優先權推測,但它猜不到哪張圖是 LCP 元素——所有 `<img>` 在初期都被當成低優先權。`fetchpriority="high"` 就是把這個知識補給瀏覽器,直接標在首屏主圖上;反過來把輪播的第二張以後、頁尾的裝飾圖標成 `low`,避免它們跟主圖搶頻寬。它和 preload 的差別是:preload 讓資源「更早被發現」,fetch priority 讓已被發現的資源「更早被下載」,兩者常一起用。

相關術語: preload (解決不同問題)

出處:第 3 段「優化 LCP 的三層做法」

見仁見智 1:42
「you likely want to use modern formats like webp」
2023 年講 webp 是對的,但今天說「現代格式」只提 webp 已經不完整。AVIF 自 2024 年起在 Chrome、Firefox、Safari、Edge 都可用,同畫質下通常又比 WebP 小 20–50%;照片類素材現在的建議寫法是 `<picture>` 依序給 AVIF → WebP → JPEG。仍然只用 WebP 不算錯,但已不是最省的選擇。
依據: AVIF 在 Safari 16.4(2023-03)後補齊,2024 年起被視為 baseline available(web.dev / MDN Baseline)
留給下一段 到這裡「怎麼讓畫面早點出現」已經有一整套答案了。但作者在段末丟下一句話:LCP 不是唯一要擔心的事。畫面出現了,使用者伸手去點卻按不動,那又是哪一個指標在量?

4. FID:畫得出來還要按得動 2:40–3:31

光是畫面出現不夠,first input delay 量的是互動性:從使用者點下按鈕,到瀏覽器處理完該次互動的事件處理器要多久,100 毫秒以內算好、300 毫秒算差。優化它基本上只有一條路——減少 JavaScript 執行時間,但又不可能不寫 JavaScript,所以改用 web worker、Partytown 搬走一部分,或用 React lazy 這類延遲載入,甚至用專為即時互動設計的 Qwik。

FID 的 100ms / 300ms 好壞分界是以刻度圖呈現,看圖才知道三段區間的相對位置。
2:50 · FID 的 100ms / 300ms 好壞分界是以刻度圖呈現,看圖才知道三段區間的相對位置。
承上 承上:上一段結尾丟下「LCP 不是唯一要擔心的事」,並問了畫面出現卻按不動該由誰負責。作者這一段就把第二個指標 first input delay 補上,填的是「互動」那一格。

推理因為前兩段解決的都是「多快看得到」,而看得到不等於用得動,所以作者接著換一個面向:互動性。他用同一套模板往下推——先給門檻(100 毫秒內算好、300 毫秒算差),再給定義(從使用者點下按鈕,到瀏覽器處理該次互動的事件處理器所花的時間),再給一句白話收束:「你不希望網站畫出來了,但上面的東西按了沒反應」。接著他做了一個關鍵推論:既然阻擋互動的是主執行緒被佔住,而佔住主執行緒的只有 JavaScript,那優化就只有一條路——減少 JavaScript 執行時間。但他馬上承認這條路走不通到底(「你也不可能把 JavaScript 全部丟掉」),於是給出三種折衷:搬走(web worker、Partytown)、延後(React lazy 之類的延遲載入)、換掉(Qwik 這種為即時互動設計的框架)。他也預告量測方式要留到擴充套件那段,因為 FID 沒有真實使用者就量不到。

AI 補充這一段有兩件事需要更正,見本段的勘誤:一是作者對 FID 的定義說反了範圍,二是 FID 本身已經被換掉了。除此之外還有一個他沒說的關鍵:截圖裡那條 100ms/300ms 的刻度是 Google 的官方判定條,綠/橘/紅三段對應 good/needs improvement/poor,而判定用的是真實使用者的第 75 百分位——意思是你自己點一次很快,不代表指標是綠的。另外「減少 JavaScript 執行時間」這句話在實務上要再拆一層:真正的兇手是「長任務」(long task,單次佔用主執行緒超過 50ms 的工作)。所以有效的做法不只是「少寫一點 JS」,而是把大工作切小、在中間主動讓出主執行緒(例如 `await scheduler.yield()` 或退而求其次的 `setTimeout` 切片),讓瀏覽器有空檔回應點擊。作者提到的三種手段其實對應三個不同的時機:web worker 是把工作搬離主執行緒、lazy loading 是延後不需要的程式碼、Qwik 的可續性(resumability)則是連 hydration 都省掉。

術語:First Input Delay (FID)Interaction to Next Paint (INP)

First Input Delay (FID)

首次輸入延遲

使用者第一次互動(點擊、按鍵)之後,瀏覽器隔多久才「開始」執行對應事件處理器的等待時間。

FID 只量等待,不量處理:如果主執行緒正忙著跑一段長任務,點擊事件就得排隊,這段排隊時間就是 FID。門檻是 100ms(好)/300ms(差)。它有兩個先天限制——只看第一次互動,而且只算延遲不算後續的處理與繪製,所以一個「點下去有反應、但兩秒後畫面才更新」的頁面 FID 仍然可以是綠的。這正是它在 2024 年被 INP 取代的原因。它也只能在真實使用者身上量到(實驗室工具沒有人去點),所以 Lighthouse 用 Total Blocking Time 當它的代理指標。

相關術語: Interaction to Next Paint (INP) (已被它取代)、Web Worker (改善它的手段)

出處:第 4 段「FID:畫得出來還要按得動」

Interaction to Next Paint (INP)

互動到下次繪製

量整個頁面生命週期中所有互動「從按下去到畫面實際更新」的耗時,取近乎最差的那一次;2024 年起取代 FID 成為核心指標。

INP 補上了 FID 漏掉的兩段:事件處理器本身跑多久,以及跑完之後畫面多久才重繪。它也不只看第一次互動,而是取整頁所有互動中接近最差的一筆,所以更貼近「這個網站用起來卡不卡」的真實感受。門檻是 200ms(好)/500ms(差),比 FID 嚴格得多——很多 FID 全綠的網站換算成 INP 就掉到橘區。優化方向因此也變了:除了減少 JavaScript 執行,還要縮短事件處理器本身的工作,並避免在處理器裡同步做大量 DOM 更新。

相關術語: First Input Delay (FID) (取代它)

出處:第 4 段「FID:畫得出來還要按得動」

Web Worker

網頁工作執行緒

瀏覽器提供的背景執行緒,可以跑 JavaScript 而不佔用負責畫面與互動的主執行緒。

Web Worker 的限制是它碰不到 DOM,只能靠 postMessage 與主執行緒交換資料,所以適合的是純運算:解析大量 JSON、影像處理、加解密、排序過濾大陣列。搬進 worker 不會讓運算變快,但會讓主執行緒空出來回應點擊,這正是互動指標要的。訊息傳遞本身有序列化成本,資料量大時要用 Transferable 物件或 SharedArrayBuffer,否則搬家的成本可能吃掉好處。

相關術語: Partytown (基於它的工具)

出處:第 4 段「FID:畫得出來還要按得動」

Partytown

Partytown

把第三方腳本(分析、廣告、聊天小工具)搬進 web worker 執行的開源函式庫。

第三方腳本是最典型的「不是我寫的、但拖慢我網站」的元凶:它們常常同步載入、又在主執行緒上做大量工作。Partytown 的巧思是用 Proxy 與同步 XHR 在 worker 裡模擬出一份 DOM 介面,讓那些原本假設自己跑在主執行緒的腳本照樣能用,實際運算卻在背景。代價是設定較繁瑣、部分依賴精確時序或直接操作 DOM 的腳本會失效,所以通常只挑分析類腳本搬。

相關術語: Web Worker (建立在其上)

出處:第 4 段「FID:畫得出來還要按得動」

lazy loading

延遲載入

把非必要的程式碼或資源延到真正需要時才載入,減少初次載入要處理的量。

延遲載入有兩個層次:資源層(圖片、iframe 加 `loading="lazy"`,捲到附近才抓)與程式碼層(動態 `import()`、React 的 `lazy` + `Suspense`,把路由或彈窗切成獨立 chunk)。它同時幫到 LCP 和互動指標,但有反效果——把首屏那張主圖也設成 lazy,反而會延後 LCP,這是常見誤用。原則是:首屏之內的東西永遠不要 lazy,首屏之外的東西盡量 lazy。

相關術語: Single Page Application (SPA) (最需要它)

出處:第 4 段「FID:畫得出來還要按得動」

Qwik

Qwik 框架

以「可續性」為核心設計的 JavaScript 框架,初次載入幾乎不執行 JavaScript,等使用者互動時才按需取回對應的程式碼。

一般框架的 SSR 流程是「伺服器產 HTML → 瀏覽器下載同一份程式碼 → 執行 hydration 重建狀態」,hydration 這一步的成本會隨應用大小線性成長,正是互動延遲的來源。Qwik 的做法是把狀態與事件監聽序列化進 HTML,瀏覽器不需要重建,等使用者真的點了某個按鈕,才去抓那一小段處理函式——所以它宣稱初次載入的 JavaScript 幾乎是常數。代價是心智模型不同(要用它的 `$` 標記切割邊界),生態系也遠小於 React 陣營。

相關術語: lazy loading (極端化的版本)

出處:第 4 段「FID:畫得出來還要按得動」

確定錯誤/已過時 2:58
「to process event handler is for that interaction」
作者把 FID 描述成「從使用者互動到瀏覽器『處理完』事件處理器」的時間,這是錯的。FID 只量到瀏覽器「開始」執行事件處理器為止的排隊延遲,處理器本身跑多久、以及跑完後畫面多久才更新,都不算在 FID 裡。這個區分很重要:一個事件處理器跑三秒的頁面,FID 仍然可能是漂亮的綠色。真正把整段涵蓋進去的是後來的 INP。
依據: web.dev/articles/fid:FID measures the time from first interaction to the time when the browser is actually able to begin processing event handlers
確定錯誤/已過時 2:43
「we also have first input delay which measures interactivity」
此段內容已過時:FID 已不再是 Core Web Vitals。Google 於 2024-03-12 正式以 INP(Interaction to Next Paint)取代 FID,並於 2024-09-09 讓 FID 完全退場(CrUX 與 PageSpeed Insights 不再回報)。今天要優化互動性應該看 INP,門檻是 200ms(好)/500ms(差),而不是影片裡的 100ms/300ms。本段其餘的優化手段(減少 JavaScript 執行時間、web worker、延遲載入)對 INP 依然適用,只是還要額外注意事件處理器本身的耗時與重繪。
依據: Google Search Central / web.dev 公告:INP 於 2024-03-12 成為 Core Web Vital,FID 於 2024-09-09 退役
留給下一段 載入與互動都有指標了,但還有一種糟糕體驗不屬於這兩者:東西看得到也按得動,卻在你手指按下去的瞬間自己跳走位置。這種「畫面亂跳」要用第三個指標來量。

5. CLS:畫面不能亂跳 3:31–4:19

最後一個指標 cumulative layout shift 量的是視覺穩定性:元素不該用意料之外的方式跳動。可用 Lighthouse 報告或 Web Vitals 擴充套件量。最常見的元凶是沒寫尺寸的圖片,補上 width/height 或改用 CSS aspect-ratio 通常就能修好;響應式圖片要換長寬比時則用 srcset。此外,被注入的廣告與動作過多的動畫也會讓 CLS 變差。作者在此收束:三個指標講完了,接著進實測。

作者示範沒有 width/height 的圖片如何把下方內容擠開,以及 aspect-ratio 的寫法,是典型的「看了才懂」畫面。
3:51 · 作者示範沒有 width/height 的圖片如何把下方內容擠開,以及 aspect-ratio 的寫法,是典型的「看了才懂」畫面。
承上 承上:上一段留下「東西看得到也按得動,卻自己跳走位置」這個沒被前兩個指標涵蓋的爛體驗。這一段就用第三個指標 cumulative layout shift 把它補起來,三格填滿。

推理因為載入(第 2 段)與互動(第 4 段)都已經有指標了,所以作者接著補上唯一還沒被量到的面向:視覺穩定性——「頁面上的元素不該用你意料之外的方式亂跳」。他這次不先給門檻數字,而是直接跳到成因,因為 CLS 的成因高度集中:最容易讓 CLS 變差的就是沒指定尺寸的圖片。原因很直接——瀏覽器在圖片載完之前不知道它多高,只好先當成 0,等圖片到了再把下面的內容整片推開。所以修法也直接:給 width 和 height,或用 CSS 的 aspect-ratio;只有響應式圖片要隨視窗換長寬比時,才需要 srcset 這種比較麻煩的做法。最後他補上兩個他控制不了的來源:被注入的廣告、動作太多的動畫。講完他就收線——「效能可以講一整天,但我認為這三個指標最重要」——把整段理論收束,準備轉進實測。

AI 補充截圖裡的寫法是 `.img { aspect-ratio: 69/420; }`,這正好示範了一件作者沒點破的事:aspect-ratio 之所以能修好 CLS,是因為它讓瀏覽器在圖片還沒到之前,就能從寬度推算出高度並預留空間——修的不是圖片,是版面預留。也因此,同樣的技巧適用於任何「內容晚到」的區塊:廣告位、嵌入的影片、非同步載入的橫幅,都應該先用固定高度或 aspect-ratio 佔位。另外兩個作者略過的重點:第一,`width`/`height` 屬性在現代瀏覽器裡不會鎖死尺寸,它只是拿來算長寬比的,所以搭配 `width: 100%; height: auto` 的響應式 CSS 完全沒有衝突——很多人以為寫了就不能響應式,這是誤解。第二,並非所有位移都算 CLS:使用者互動後 500 毫秒內發生的位移會被豁免(因為那是使用者預期的),所以點按鈕展開選單不會扣分,但廣告自己插進來會。至於動畫,安全的做法是只動 `transform` 與 `opacity`,它們在合成階段處理、不觸發版面重排,也就不會產生位移分數。

術語:Cumulative Layout Shift (CLS)

Cumulative Layout Shift (CLS)

累積版面位移

把頁面上所有非預期的元素位移量累加起來的分數,代表視覺穩定性;0.1 以內算好、超過 0.25 算差。

CLS 是三個指標裡唯一沒有單位的:它是「位移影響的畫面比例 × 位移距離比例」的乘積累加,所以一個佔滿螢幕的元素稍微動一下,可能比一個小角標大幅移動還嚴重。它現在採計的是「session window」——取整頁生命週期中最糟的那一段連續位移,而不是全部相加,避免長頁面被無限累積懲罰。最容易被忽略的來源是網頁字型:自訂字型晚到時整段文字換字體,行高一變就整頁位移(FOUT),用 `font-display: optional` 或 `size-adjust` 可以壓下來。

相關術語: aspect-ratio (最常用的修法)、Core Web Vitals (其中一員)

出處:第 5 段「CLS:畫面不能亂跳」

aspect-ratio

長寬比屬性

CSS 屬性,指定元素的寬高比,讓瀏覽器在內容還沒載入時就能算出並預留正確的高度。

aspect-ratio 把「預留空間」這件事從 hack 變成語意化的一行 CSS——在它之前大家用的是 padding-top 百分比的 padding hack,難讀又難維護。它對圖片以外的東西同樣有效:嵌入的 iframe、地圖、影片播放器都常常是位移來源。要注意它與明確 `height` 衝突時會被 height 覆蓋;而在圖片上,`<img>` 的 `width`/`height` 屬性其實會自動產生一個預設的 aspect-ratio,所以兩種寫法擇一即可,只有需要跟原圖不同的比例(例如裁切成方形卡片)時才必須手寫。

相關術語: Cumulative Layout Shift (CLS) (用來降低它)

出處:第 5 段「CLS:畫面不能亂跳」

srcset

響應式圖片來源集

`<img>` 的屬性,列出同一張圖的多種尺寸或版本,讓瀏覽器依螢幕寬度與像素密度自己挑一張。

srcset 解決的是「同一張圖在手機上太大、在桌機上太小」:搭配 `sizes` 告訴瀏覽器這張圖在版面裡實際會佔多寬,瀏覽器就能在下載前挑對檔案,省下的頻寬直接反映在 LCP 上。它與作者提到的情境有一個重要差別——單純換尺寸用 `srcset` 就夠;如果連長寬比或構圖都要換(藝術指導,art direction),要用 `<picture>` + `<source media="...">`。也因為不同斷點可能是不同比例,這種情況才沒辦法只靠一組固定的 aspect-ratio 解決。

相關術語: aspect-ratio (比例會變時的替代)、WebP (常一起使用)

出處:第 5 段「CLS:畫面不能亂跳」

留給下一段 三個指標到這裡全部講完,讀者手上有了完整的量測語言。但這些都還是紙上的定義——真正的問題是:怎麼在自己的網站上實際量到這些數字,而且知道是「哪一個元素」害的?

6. Web Vitals 擴充套件:單頁診斷 4:19–5:21

Chrome 團隊新出的 Web Vitals 擴充套件,安裝後到設定打開 console logging,開任一網頁的 console 就會看到 CLS 與 LCP 的記錄。LCP 會直接指出是哪個元素造成的,並拆解出 time to first byte 與 element render delay;layout shift 會列出造成位移的 DOM 元素;點擊頁面則會記錄 first input delay 與之後每次互動。作者說它的價值在於「直接指出該修哪一個東西」,但缺點是一次只能看一頁。

擴充套件在 console 印出的 CLS / LCP 記錄長什麼樣,是這段唯一的操作證據。
4:33 · 擴充套件在 console 印出的 CLS / LCP 記錄長什麼樣,是這段唯一的操作證據。
LCP 被拆成 time to first byte 與 element render delay 的細項畫面,聽不到數字結構。
4:46 · LCP 被拆成 time to first byte 與 element render delay 的細項畫面,聽不到數字結構。
點擊後出現的 first input delay 記錄,示範互動指標怎麼被量到。
4:57 · 點擊後出現的 first input delay 記錄,示範互動指標怎麼被量到。
承上 承上:上一段結尾問的是「怎麼在自己的網站上實際量到這些數字、而且知道是哪個元素害的」。作者這一段就給出第一個答案——Chrome 團隊新推出的 Web Vitals 擴充套件。

推理因為前三段建立的都是定義,而定義沒辦法告訴你「這一頁該改哪裡」,所以作者接著要一個能落到具體元素的工具。他刻意選最低摩擦的路徑:安裝擴充套件、到設定打開 console logging、開一頁看 console,三步就有數字。接著他依序展示這個工具能回答什麼——LCP 不只給秒數,還直接指出是哪一個元素造成的,並拆成 time to first byte 與 element render delay 等子項;layout shift 會列出實際造成位移的 DOM 元素;點一下頁面就會記到 first input delay 與之後每一次互動。這三件事正好一一對應前面三個指標,等於把理論逐條驗收。最後他給出這個工具的價值判斷(「它最強的是精準指出該修哪一個東西」)與它的邊界(一次只能看一頁),而這個邊界就是他推進下一段的槓桿。

AI 補充三張截圖比作者的口述多給了不少東西。第一張是 fireship.io 的 console,可以看到記錄的格式就是 `[Web Vitals Extension] LCP 136 ms (good)`、`CLS 0.00 (good)`——指標、數值、評級一行到位,這是它比 Lighthouse 輕的地方:不用跑一輪稽核,正常瀏覽就在收數據。第二張展開 LCP,資訊量最大:LCP element 直接印出那個 `<img src="/courses/supabase/img/featured.webp">`,下面的表格把 136ms 拆成 Time to First Byte 24、Resource load delay 7、Resource load time 0、Element render delay 105。作者口述只提了頭尾兩項,但這張表其實是四項,而且四項的分佈就是診斷書——這一頁的 105ms 全壓在 element render delay,代表圖片早就下載完了、卡的是渲染,那麼壓縮圖片或換 CDN 都不會有用,該查的是 render blocking 的 CSS 或 JS。反過來如果 TTFB 佔大宗,問題在伺服器或網路,跟前端怎麼改都無關。第三張展開的其實是 CLS 而不是 FID:它列出 Layout shift score 0.0088 與造成位移的 `<ul class="flex justify-center items-center">`、`<main class="prose ...">`,滑鼠移過去還會在頁面上把那個元素框起來——這就是作者說的「精準指出該修哪一個」。一個實務提醒:擴充套件量到的是你這一台機器、這一次瀏覽的數字,屬於單次觀測;Google 判定用的是真實使用者第 75 百分位,兩者不會一致,這個工具的用途是定位問題而不是驗收成績。

術語:Web Vitals Chrome extensionTime to First Byte (TTFB)

Web Vitals Chrome extension

Web Vitals Chrome 擴充套件

Chrome 團隊官方出的擴充套件,在你正常瀏覽網頁時即時量測並在 console 印出 LCP、CLS、INP 等指標與肇因元素。

它和 Lighthouse 的分工很清楚:Lighthouse 是實驗室測試,用固定的節流條件跑一輪、給一份報告;這個擴充套件是在真實瀏覽過程中被動觀測,所以能量到需要使用者互動才產生的指標。打開設定裡的 console logging 是關鍵一步,不開就只有工具列上的小徽章、看不到肇因元素。它現在回報的是 INP 而不是影片裡的 FID。要注意數據來自你自己的機器與網路,適合用來定位「哪個元素有問題」,不適合拿來當網站的實際成績。

相關術語: Lighthouse (互補的實驗室工具)、Core Web Vitals (量測它們)

出處:第 6 段「Web Vitals 擴充套件:單頁診斷」

Time to First Byte (TTFB)

首位元組時間

從發出請求到收到伺服器回應第一個位元組的時間,涵蓋 DNS、連線建立、伺服器處理與網路往返。

TTFB 是 LCP 的地板:LCP 不可能比 TTFB 快,所以 TTFB 一高,前端怎麼優化都有上限。它慢的原因通常不在前端——後端查詢太慢、沒有快取、伺服器離使用者太遠(CDN 要解決的正是這一項)、或重新導向多繞了一圈。一般建議控制在 800ms 以內。它不是 Core Web Vitals 成員,而是診斷用的輔助指標:拿它跟 LCP 相減,就能判斷問題出在伺服器端還是瀏覽器端。

相關術語: Content Delivery Network (CDN) (常用的改善手段)、Largest Contentful Paint (LCP) (它的下限)

出處:第 6 段「Web Vitals 擴充套件:單頁診斷」

element render delay

元素渲染延遲

LCP 拆解的最後一段:資源已經下載完,到它真正被畫到畫面上之間的等待時間。

LCP 官方拆成四段:TTFB、resource load delay(發現資源到開始下載的空窗)、resource load time(實際下載)、element render delay(下載完到畫出來)。這種拆法的價值在於每一段都指向不同的修法:TTFB 高改後端或 CDN、load delay 高用 preload、load time 高壓縮圖片、render delay 高就去找阻擋渲染的 CSS 或 JavaScript。截圖裡 fireship.io 的 105ms 全落在 render delay,正是最後這一類。理想的分佈是 TTFB 與 load time 佔大宗、兩個 delay 接近 0。

相關術語: render blocking JavaScript (常見的元凶)、Time to First Byte (TTFB) (同一份拆解)

出處:第 6 段「Web Vitals 擴充套件:單頁診斷」

留給下一段 這個工具能把單一頁面的問題釘到具體元素,但作者立刻點出它的天花板:一次只能看一頁。網站有幾百甚至幾千頁時,人不可能一頁一頁開——那就需要一個能一次掃完整站的工具。

7. Unlighthouse:整站掃描與實測 5:21–6:43

單頁工具在幾百上千頁的網站上不管用,所以作者介紹開源的 Unlighthouse:對全站每一頁平行跑 Lighthouse,幾分鐘掃完數百頁,用法是 npx unlighthouse 加網址。他用它掃自己的站,找出原本不會發現的爛頁面;再拿熱門網站實測——Amazon 意外地不錯但有明顯 CLS 問題,Google 表現極好,Reddit 與 GitHub 平均約 90 分,astro.build 幾乎全部滿分。最後提到它有 SDK,可以接進 CI。

Unlighthouse 的即時掃描介面,是理解「整站平行掃描」長什麼樣的關鍵畫面。
5:38 · Unlighthouse 的即時掃描介面,是理解「整站平行掃描」長什麼樣的關鍵畫面。
Amazon 的實測分數,對照作者「本來以為會很差」的預期落差。
5:57 · Amazon 的實測分數,對照作者「本來以為會很差」的預期落差。
astro.build 幾乎全滿分的成績單,是全片的收尾證據。
6:24 · astro.build 幾乎全滿分的成績單,是全片的收尾證據。
承上 承上:上一段留下的天花板是「單頁工具在幾百上千頁的網站上不管用」。作者這一段就用 Unlighthouse 把量測從一頁擴大到整站,並且順勢用真實網站的分數替前面所有原則做驗收。

推理因為手動一頁一頁量在大型網站上不可行,所以作者接著找的是規模化的工具:Unlighthouse 會對網站每一頁都跑一次 Lighthouse,而且全部平行處理,幾分鐘就能掃完上百頁。他先降低嘗試成本(開個新資料夾、`npx unlighthouse` 加網址就跑),再給自身經驗當佐證——他掃自己的站,找到幾個「不掃根本不會發現」的爛頁面,這正是整站掃描相對單頁工具的真正價值:發現你不知道自己有問題的地方。有了工具,他才敢做最後一步——拿真實網站當對照組:Amazon 出乎意料地不錯(但用擴充套件看有明顯 CLS 問題,回頭呼應第 5 段),Google 表現極好(合理,規則是他們訂的),Reddit 與 GitHub 平均約 90,astro.build 幾乎滿分。這串排名的作用不是八卦,而是證明前面講的原則在真實世界會產生可見的分差。最後他補上 SDK 可接進 CI,把一次性的檢查升級成持續的防線——這是整支影片從「知道」走到「守得住」的最後一步。

AI 補充截圖補了幾個口述沒有的細節。第一張是命令的正式寫法:`npx unlighthouse --site <your-site>`——網址要跟在 `--site` 後面,光打網址是不會動的,這是作者口述略過的一步。第二張是掃 amazon.com 的即時畫面:ROUTES 147、worker 進度 44%(154/354)、DEVICE 是 Emulated Mobile,左側分成 Performance/Accessibility/Best Practices/SEO 四欄,每個路由的狀態在 In progress 與 Waiting 之間流動——這張圖真正說明的是「平行掃描」長什麼樣,以及它會自動爬站找出路由並依樣板分組(Coupons-slug、Smart-Home-slug…),你不用自己列 URL 清單。要注意此時 SITE SCORE 還在轉圈,所以作者口中「Amazon 表現不錯」的結論並不在這張畫面上。第三張是 astro.build 的成績單:SITE SCORE 99、36 個路由,Performance 100、Accessibility 99、Best Practices 98、SEO 100,逐列幾乎都是四個 100。這裡有個容易誤讀的地方:Amazon 有 147 個路由、astro.build 只有 36 個,掃描範圍差了四倍,而且預設在模擬行動裝置與節流條件下跑,所以這些數字適合當同一支工具的相對參考,不適合當精確排名。最後,「接進 CI」的實務做法是設一條分數門檻,PR 掉到門檻以下就擋——這比「上線後才發現變慢」有用得多,也是整支影片唯一一個把效能變成流程而非一次性活動的建議。

術語:Continuous Integration (CI)

Unlighthouse

Unlighthouse 整站掃描工具

開源 CLI 工具,自動爬出網站所有路由並平行跑 Lighthouse,用一個即時網頁介面呈現全站的分數與截圖。

Unlighthouse 解決的是 Lighthouse 的規模問題:官方工具一次一頁,而真正拖垮網站平均體驗的往往是你從沒點開過的那些頁。它會從 sitemap 或爬蟅找出路由,還會依 URL 樣板分組(例如所有商品頁歸成一組只抽樣幾頁),避免一萬個同構頁面白跑一萬次。用法是 `npx unlighthouse --site <網址>`,跑完會開一個本機介面,也可以輸出靜態報告。它有 SDK 與 CI 整合,能設定分數門檻讓不合格的變更擋在合併之前。要記得它底層仍是 Lighthouse,所以拿到的是實驗室數據,不是真實使用者資料。

相關術語: Lighthouse (包在外面的整站版)、Continuous Integration (CI) (可接進去)

出處:第 7 段「Unlighthouse:整站掃描與實測」

Astro

Astro 框架

以「預設不送 JavaScript」為原則的網站框架,把頁面在建置時就渲染成 HTML,只有需要互動的元件才單獨載入。

Astro 的核心概念叫 islands architecture(群島架構):整頁是靜態 HTML 的海,只有少數真的需要互動的元件是「島」,各自獨立 hydrate。相較於整頁 hydration 的 SPA,這直接砍掉大部分初次載入要執行的 JavaScript,所以互動指標與 LCP 天生就好看——這也是它在 Unlighthouse 掃描裡幾乎滿分的結構性原因,而不是它「調得比較好」。代價是它偏向內容型網站(部落格、文件、行銷頁);重度互動的應用程式,優勢就沒那麼明顯。

相關術語: Single Page Application (SPA) (相反的取捨)、lazy loading (同一個思路)

出處:第 7 段「Unlighthouse:整站掃描與實測」

Continuous Integration (CI)

持續整合

每次程式碼變更都自動跑一輪建置與檢查的流程,讓問題在合併前就被擋下來。

把效能檢查放進 CI,是這支影片裡唯一一個「防守」而非「補救」的建議:效能會退步,而且退步通常來自一次不起眼的相依套件升級或一張沒壓縮的新圖,人工抽查抓不到。常見做法是設效能預算(performance budget)——例如 LCP 不得超過 2.5 秒、JavaScript bundle 不得超過某個大小——超標就讓該次建置失敗。要注意 CI 機器的效能會波動,所以門檻要留緩衝,或改用多次取中位數,否則會不斷出現假警報。

相關術語: Unlighthouse (可跑在裡面)

出處:第 7 段「Unlighthouse:整站掃描與實測」

見仁見智 5:41
「it'll bring up a UI to show you how bad your website performance is in real time」
這句在畫面上的呈現與口述有落差:截圖裡掃 amazon.com 時 SITE SCORE 還在轉圈、worker 進度才 44%,也就是「即時」指的是路由狀態與逐頁分數陸續回填,整站總分要掃完才算得出來。此外預設是在模擬行動裝置與節流條件下跑的實驗室數據,跟真實使用者的 Core Web Vitals(第 75 百分位)不會一致,所以拿它比較不同網站時只能當相對參考。
依據: 截圖 frames/s07_357.jpg:amazon.com、ROUTES 147、WORKER PROGRESS 44% 154/354、DEVICE Emulated Mobile
留給下一段 總結收束:三個指標(看得到、按得動、不亂跳)、一套優化手段、一個單頁診斷工具與一個整站掃描工具,最後用真實網站的分數證明這條路走得通,並以接進 CI 讓它可持續。

4. 總結

作者先立下一個非技術的前提:使用者注意力極短,網站慢就會跳走、直接等於少賺錢,於是「效能」被換算成商業問題,需要可量測的指標。接著他用同一套模板推導三個指標——LCP 量載入(門檻 2.5 秒/4 秒,靠壓縮資源、webp、CDN、避開 render blocking JavaScript、preload 與 fetch priority 來改善);FID 量互動(門檻 100ms/300ms,唯一解是減少 JavaScript 執行時間,手段是 Web Worker、Partytown、lazy loading,或改用 Qwik 這類為即時互動設計的框架);CLS 量視覺穩定(元凶多半是沒寫尺寸的圖片,補上 width/height 或 aspect-ratio、響應式用 srcset,另外小心廣告注入與過度動畫)。三個指標建立起量測語言之後,問題就從「該量什麼」變成「怎麼在自己的網站上量到、而且知道是哪個元素害的」——Web Vitals Chrome 擴充套件能把 LCP 釘到具體 DOM 元素並拆出 TTFB 與 element render delay,但它一次只能看一頁;於是再往上一層,用 Unlighthouse 平行掃描整站,幾分鐘掃完數百頁,找出人工不可能發現的爛頁面。最後作者不用意見收尾,而是讓 Amazon、Google、Reddit、GitHub 與 astro.build 的實測分數說話,並用「Unlighthouse 有 SDK,可接進 CI」把一次性檢查變成持續的流程。

勘誤總整理

確定錯誤/已過時見仁見智(取決於版本或情境)

段落原話(transcript 逐字)說明
4. FID:畫得出來還要按得動
2:43
「we also have first input delay which measures interactivity」此段內容已過時:FID 已不再是 Core Web Vitals。Google 於 2024-03-12 正式以 INP(Interaction to Next Paint)取代 FID,並於 2024-09-09 讓 FID 完全退場(CrUX 與 PageSpeed Insights 不再回報)。今天要優化互動性應該看 INP,門檻是 200ms(好)/500ms(差),而不是影片裡的 100ms/300ms。本段其餘的優化手段(減少 JavaScript 執行時間、web worker、延遲載入)對 INP 依然適用,只是還要額外注意事件處理器本身的耗時與重繪。
依據: Google Search Central / web.dev 公告:INP 於 2024-03-12 成為 Core Web Vital,FID 於 2024-09-09 退役
4. FID:畫得出來還要按得動
2:58
「to process event handler is for that interaction」作者把 FID 描述成「從使用者互動到瀏覽器『處理完』事件處理器」的時間,這是錯的。FID 只量到瀏覽器「開始」執行事件處理器為止的排隊延遲,處理器本身跑多久、以及跑完後畫面多久才更新,都不算在 FID 裡。這個區分很重要:一個事件處理器跑三秒的頁面,FID 仍然可能是漂亮的綠色。真正把整段涵蓋進去的是後來的 INP。
依據: web.dev/articles/fid:FID measures the time from first interaction to the time when the browser is actually able to begin processing event handlers
3. 優化 LCP 的三層做法
1:42
「you likely want to use modern formats like webp」2023 年講 webp 是對的,但今天說「現代格式」只提 webp 已經不完整。AVIF 自 2024 年起在 Chrome、Firefox、Safari、Edge 都可用,同畫質下通常又比 WebP 小 20–50%;照片類素材現在的建議寫法是 `<picture>` 依序給 AVIF → WebP → JPEG。仍然只用 WebP 不算錯,但已不是最省的選擇。
依據: AVIF 在 Safari 16.4(2023-03)後補齊,2024 年起被視為 baseline available(web.dev / MDN Baseline)
7. Unlighthouse:整站掃描與實測
5:41
「it'll bring up a UI to show you how bad your website performance is in real time」這句在畫面上的呈現與口述有落差:截圖裡掃 amazon.com 時 SITE SCORE 還在轉圈、worker 進度才 44%,也就是「即時」指的是路由狀態與逐頁分數陸續回填,整站總分要掃完才算得出來。此外預設是在模擬行動裝置與節流條件下跑的實驗室數據,跟真實使用者的 Core Web Vitals(第 75 百分位)不會一致,所以拿它比較不同網站時只能當相對參考。
依據: 截圖 frames/s07_357.jpg:amazon.com、ROUTES 147、WORKER PROGRESS 44% 154/354、DEVICE Emulated Mobile

5. 推薦三個下一步

1. 往下挖深:INP 取代 FID 之後的互動效能

影片講的 FID 只量「第一次互動的延遲」,而且已於 2024 年被 Interaction to Next Paint 取代——它量的是整個互動到畫面更新完成的時間,門檻與優化手段都跟 FID 不同。這是這條推理鏈上最大的過時缺口。

YouTube 搜尋:Interaction to Next Paint INP explained INP optimization JavaScript long tasks Core Web Vitals 2025 update

2. 往旁邊對照:實驗室數據 vs 真實使用者數據

影片用的 Lighthouse 與 Unlighthouse 都是實驗室量測,跑在你自己的機器與網路上;但 Google 拿來影響搜尋排名的是真實使用者的 CrUX 資料。搞懂兩者為什麼會差很多,才知道分數 90 到底代表什麼。

YouTube 搜尋:field data vs lab data Core Web Vitals Chrome UX Report CrUX tutorial Real User Monitoring web performance

3. 往上應用:把效能預算納入 CI 流程

影片最後只提了一句「Unlighthouse 有 SDK 可以接進 CI」就結束。真正讓效能不退化的做法是設定 performance budget、在 PR 上自動擋住變慢的改動——這是把一次性檢查變成工程紀律的那一步。

YouTube 搜尋:Lighthouse CI setup tutorial performance budget GitHub Actions unlighthouse CI integration

📄 全部影片 · 主題區: 歷史參考(已過時)