前陣子幫一個站做健檢,手機版跑出來 Performance 只有 55 分,首屏要等 13.8 秒才出現內容。同樣一支網站速度優化的流程,如果你只會打開網頁版工具看分數,大概就卡在「知道慢,但不知道要改哪一行」。這篇要談的是用 Lighthouse CLI 從掃描到改碼的完整做法:先講這個命令列工具是什麼,再用一個真實案例,一步步把分數從 55 修到 92。
先給還在趕時間的人一句話結論:網站速度優化最有效的順序,是先用工具掃出「渲染阻塞」的資源、再處理沒壓縮的圖片、最後才是零碎的 CSS/JS。多數網站慢,慢在字型和圖片,不在主機。
Lighthouse CLI 是什麼?跟網頁版差在哪
Lighthouse 是 Google 做的網頁品質稽核工具,會針對一個網址跑出 Performance、Accessibility、Best Practices、SEO 四個面向的分數。大部分人第一次接觸它,是在 Chrome 開發者工具裡的那個「Lighthouse」分頁,或是 PageSpeed Insights 網站。
那個 GUI 版本好上手,但有兩個問題。第一,每次都要手動開瀏覽器、點按鈕、等它跑完,沒辦法排進自動化流程。第二,它只給你一份看起來很漂亮的網頁報告,你沒辦法把裡面的數據抓出來丟給程式處理。
Lighthouse CLI 是同一個引擎的命令列版本。你用 npm 裝好之後,一行指令就能掃一個網址,而且它會同時吐出兩份東西:一份給人看的 HTML 報告,一份給程式解析的 JSON。JSON 這份是關鍵,因為你可以用 jq 或任何腳本把「哪個資源在拖慢頁面、可以省幾秒」精準抓出來,直接對應到你要改的那支檔案。
| 比較 | 網頁版(PageSpeed / DevTools) | Lighthouse CLI |
|---|---|---|
| 操作方式 | 手動開瀏覽器、點按鈕 | 一行指令,可寫進腳本 |
| 輸出 | 只有網頁報告 | HTML 報告 + 可解析的 JSON |
| 適合 | 快速看分數 | 掃描後直接對應到程式碼修改 |
| 自動化 | 不行 | 可排進 CI 或定期監測 |
簡單說,如果你只是想知道分數,網頁版就夠了。但如果你想掃完直接動手改外掛或佈景主題,CLI 這條路才走得下去。
怎麼安裝與掃描
安裝很單純,有 Node.js 環境的話一行就好:
npm install -g lighthouse
裝完確認一下版本,我這次用的是 12.8.2:
lighthouse --version
這裡有個常被問的問題:要從主機上掃 localhost,還是從自己電腦掃公開網址?答案是後者。從你電腦掃公開網址,量到的是 DNS、CDN、主機回應、實際傳輸的每個檔案,也就是真人上站的體驗。從主機掃 localhost 會少掉網路這一段,數字漂亮但不真實。
而且 Google 排名主要看手機版,所以預設就跑 mobile:
lighthouse https://www.example.com \
--output=html --output=json \
--output-path=./report \
--form-factor=mobile --screenEmulation.mobile=true \
--chrome-flags="--headless"
跑完會拿到 report.report.html 和 report.report.json 兩個檔。Lighthouse 只是像訪客一樣載入頁面,唯讀、不會改到你的網站,所以拿來掃正式站是安全的。
讀懂報告:問題到底出在載入還是執行
拿到 JSON 之後,先看四個分數和幾個核心指標。這次的案例掃出來長這樣:
Performance: 55
Accessibility: 91
Best Practices: 100
SEO: 100
First Contentful Paint: 13.8 s
Largest Contentful Paint: 17.4 s
Total Blocking Time: 0 ms
Cumulative Layout Shift: 0
這組數字其實藏著很明確的線索。FCP 13.8 秒、LCP 17.4 秒都慢得離譜,但 TBT 是 0、CLS 也是 0。這代表什麼?TBT(Total Blocking Time)量的是 JavaScript 執行時卡住主執行緒的時間,它是 0,表示 JS 沒有問題。CLS(Cumulative Layout Shift)量的是版面有沒有亂跳,也是 0,表示排版很穩。
換句話說,瓶頸在「載入」而不在「執行」,瀏覽器遲遲畫不出畫面,是在等某個檔案下載回來。這時候就要往網路請求那邊挖。
揪出元凶:渲染阻塞的 Google 字型
繼續解析 JSON 裡的 opportunities(改善機會)和伺服器回應時間,兩個關鍵數字跳出來:
伺服器回應時間:Root document 只花 80 ms(很快)
Eliminate render-blocking resources:可省 12.2 s
主機回應只花 80 毫秒,完全沒問題。真正拖慢首屏的是「渲染阻塞資源」,一個人就吃掉 12.2 秒。再往下追是哪個檔案,答案很乾脆:
[232KB Stylesheet] https://fonts.googleapis.com/css2?family=Playfair+Display...&Noto+Serif+TC...&Noto+Sans+TC...
[194KB Image] .../mimiapp-xxx-1.jpg
[186KB Image] .../mimiapp-xxx-5.jpg
一支 Google Fonts 的 CSS,232KB,而且後面還牽出一堆 80 到 120KB 的中文字型 woff2。前 15 大網路請求裡,有 12 個是字型。這支 CSS 印在 <head> 裡是會阻塞渲染的,瀏覽器要先把它下載、解析完才肯畫第一個字,手機慢速網路下光這一步就好幾秒。
回頭看佈景主題的 functions.php,它一次載了三套字型、七種字重:Playfair Display 四種、Noto Serif TC 三種、Noto Sans TC 四種。中文字型每個字重都是 MB 級的大檔,載這麼多本來就會慢。
到這裡,網站速度慢的根因已經從「感覺很慢」變成「functions.php 第 45 行的字型載入方式有問題」。這就是用 Lighthouse CLI 做網站速度測試的價值:它把模糊的體感,變成可以對應到某一行程式碼的具體問題。
修復流程:三步,全部在佈景主題
根因確定後,修法全部落在佈景主題的 functions.php,不用動任何外掛。
第一步,字型改成非阻塞載入
這是省最多的一步。原本字型 CSS 是同步載入、會擋住渲染,改成先 preload、載完再 onload 套用,首屏就不用等它。常見寫法是用 media='print' 的技巧讓瀏覽器不把它當關鍵資源,載完再切回 all:
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?..."
media="print" onload="this.media='all'">
<noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?..."></noscript>
<noscript> 那行是給關掉 JavaScript 的訪客的 fallback,確保他們還是看得到字型。同時補上 fonts.googleapis.com 的 preconnect,原本只 preconnect 了 fonts.gstatic.com,少了這個,光補上去就能再省 0.34 秒:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
第二步,砍掉沒用到的字重
載了七種字重,但 CSS 裡真的有引用的沒那麼多。動手砍之前一定要先確認,不然會砍到正在用的、畫面就爆了。做法是把佈景主題 CSS 裡每個 font-weight 撈出來,對應到最近的 font-family,就知道每套字型實際用了哪幾種。這次比對出來的結果是:
- Playfair Display:只用到 600、700,多載的 500 和斜體可砍
- Noto Serif TC:400、500、600、700 都有用,維持不動
- Noto Sans TC:只用到 400、700,多載的 300、500 可砍
砍掉的都是 CSS 沒引用的字重,所以視覺零變化,但字型 CSS 和後續要下載的 woff2 都瘦了一圈。
第三步,圖片轉 next-gen 格式
這步優先度較低,但也值得做。報告裡那兩張首頁 jpg(194KB、186KB)沒有用 next-gen 格式,轉成 WebP 大約能再省 0.5 秒。WordPress 可以用外掛批次轉,或在上傳流程裡自動處理。
成果:55 分修到 84 分
清完快取,重跑一次 Lighthouse CLI 驗證,同一支網址、同樣 mobile,前後對照如下:
| 指標 | 修改前 | 修改後 | 變化 |
|---|---|---|---|
| Performance | 55 | 84 | +29 |
| First Contentful Paint | 13.8 s | 1.3 s | 快 91% |
| Largest Contentful Paint | 17.4 s | 4.3 s | 快 75% |
| Speed Index | 13.8 s | 2.2 s | 快 84% |
真正讓分數暴增的是第一步的字型非阻塞載入,首屏不用再等字型,FCP 直接從 13.8 秒掉到 1.3 秒。剩下 LCP 還有 4.3 秒的空間,瓶頸就在那兩張還沒轉 WebP 的首頁圖,這是下一輪要處理的。另外提一個小代價:字型改用 swap 之後,CLS 從 0 微升到 0.054,那是字型切換造成的輕微位移,影響很小,可以先不管。
沒時間自己弄?把網站效能交給我
如果你的網站也慢,但沒空一支檔案一支檔案追,我提供 WordPress 網站效能最佳化 服務:用同一套 Lighthouse CLI 流程幫你診斷、實際修好程式碼,並交付修改前後的分數對照報告:
一套可以重複用的流程
回頭看,這次網站速度優化其實就是同一套流程跑一遍,換到別的網站也適用:
- 掃描 — 用 Lighthouse CLI 掃公開網址,同時產出 HTML 和 JSON
- 判讀 — 看 TBT 和 CLS 是不是 0,先分清楚問題在「載入」還是「執行」
- 定位 — 從 JSON 的 render-blocking 和最大請求清單,找出具體是哪個檔案
- 對應 — 把那個檔案對回佈景主題或外掛的某一行程式碼
- 修復 — 字型非阻塞、砍字重、圖片 next-gen,由影響大到小
- 驗證 — 清掉 CDN 快取,重掃確認分數,別忘了快取這一層
網頁版工具能告訴你「幾分」,但要從幾分變成「改哪一行」,命令列的 JSON 才是真正好用的地方。如果你的問題不在前端載入、而是後台或資料庫變慢,那又是另一條排查路線,可以參考 WordPress 網站變慢?活用 WP-CLI 找出問題,以及針對 API 慢的 如何提升 WordPress REST API 的請求速度。