Lighthouse 分數提高攻略 - Next.js
2025-04-221.08Front EndNextjsPerformanceReact
最近在開發公司日本官網,研究了一番 Lighthouse 提高分數的方法,因 Lighthouse 分數對網站品質的影響非常直接,不只工程師自己會參考,連顧客看到網站體驗好不好,來檢視公司產出的品質。它幾乎就是評估網站品質的最直觀量化依據之一。
其中 Lighthouse 的四大項目中,「效能(Performance)」是最難搞的一個。其他像是「無障礙(Accessibility)」、「最佳做法(Best Practices)」、「SEO」老實說都還算容易加分(至少可以照 checklist 改),但效能這塊,完全是另一回事。
先講無障礙、SEO、Best Practices(比較容易處理)
這三個項目其實照著工具或官方建議就蠻容易滿分 :
無障礙(Accessibility)
我是用 shadcn/ui 的元件庫,它天生就有考慮很多無障礙的東西,像是:
元件都有
aria-*
屬性Dialog、Popover 這類互動元件有正確的 focus 管理
支援鍵盤操作
不過還是有遇到一些地方要跟 UI 設計師協調,例如文字與背景對比不夠、hover 狀態太不明顯等,以這次開發為例,我們就有針對某些字體顏色做微調,這點真的得溝通協作才能搞好。
Best Practices
其實用 Next.js 的話大致上沒太大問題,很多安全性或結構上的東西框架都幫你處理好了,例如:
自動防範 path traversal 攻擊
有內建的 Image 最佳化
禁止 inline script 等等
SEO
這邊要提醒的是:
每頁只能有一個
h1
(這個不少開發者都沒注意)h2
~h6
標籤要順序遞增,不能亂跳,不要h2
接h4
這種meta 標籤該寫的要寫,像
description
、og:image
、robots
等等
接下來進入正題:效能(Performance)
這一項分數難拉的原因有幾個:
牽涉到使用者裝置、網路速度
不是單靠設定可以解決,需要針對真實瀏覽體驗做細緻調整
你可能在某個地方塞了一個字體、圖片或套件,整體分數就被拖垮
以下是這次實戰中踩到的一些坑,還有具體怎麼優化:
一 、避免大量網路資源
這一項是我在 Lighthouse 最常看到被扣分的項目之一,因為它直接關係到首屏載入時間,下面幾個東西特別容易出事:
1. 字體
為了日文排版美觀,引用了 Google Fonts 裡幾個日文字體,結果 Lighthouse 一測直接大扣分。因為單是字體就佔了整體傳輸資源的 50~60%。


解法是這樣的:
若真的要用 Google Fonts,請只載入需要的字重和子集,不要整包。
→ 我採用的是 Next.js 內建的next/font/google
,可以選擇只載你需要的部分。更好的做法:自託管字體,只打包你要的部分,完全不經外部請求,穩又快。
或乾脆改用系統字體 stack:日文可參考這個組合 →
"游ゴシック体", "Yu Gothic", "Hiragino Kaku Gothic ProN", sans-serif
。
2. 首屏加載的圖片
因為公司官網本身圖片就偏多,如果一進頁面就全部載入,勢必影響這個項目評分。
解法:
使用 lazy load:不要一進來就載圖,讓瀏覽器「看到再載」。
Next.js 的<Image>
元件預設就已經有 lazy loading 功能,基本上拿來用就很夠用。
3. 第三方插件
像 reCAPTCHA 這類第三方服務,只是為了某一個功能(像是底部的聯絡我們表單),但它本身會引入一堆額外 JS,而且大多是同步載入,會嚴重拖累效能。
解法:
我自己封裝了一個
useIntersectionObserver
的 hook,搭配ref
去監聽表單區塊的出現時機;只有當使用者「真的滑到底部」看到表單時,才會動態載入 reCAPTCHA 的 script。

二 、最大內容繪製元素(LCP)
LCP(Largest Contentful Paint)指的是「畫面中最主要的內容載入完成的時間」,通常是一張 Hero 圖或大的標題文字。
常見問題:
Hero 圖是用
<img src="...">
而不是<Image />
太大張沒壓縮,或直接塞了一張 4K 畫質的背景圖
解法:
Hero 圖建議用 Next.js 的
<Image />
並加上priority
,會幫我們做preload
採用 mobile-first 的圖片策略,讓不同螢幕尺寸載入不同大小的圖片
轉成 WebP

三 、 DOM 結構不要太複雜
有時候 UI 太動態、太多巢狀層級會讓 DOM 太大,尤其是用了什麼無限列表、複雜的元件樹:
DOM 元素總數盡量控制在幾千以內
深層巢狀不要超過 10 層
沒必要的 div、span,請勇敢刪掉(不要為了排版加一堆 wrapper)
四 、減少無用的 CSS
過去使用大型 UI library(像 MUI、Ant Design)時,常常會引入一大堆你根本沒用到的 CSS,結果造成首屏載入 CSS 體積爆炸,Lighthouse 效能分數低落。
這次我選擇使用 shadcn,它的最大優點就是「你用什麼,就只引入什麼」。所有元件都是 base on Tailwind + Radix 的組合,不像 UI 庫會一次塞一包。
換句話說:
沒有多餘的樣式,載入快
所有樣式都在你控制範圍內,要客製也方便
不怕 purgeCSS 或 Tailwind 把你沒用到的 class 清不掉
簡單來說,shadcn 的設計哲學很接近「按需載入」,比起傳統 UI 庫,在 Lighthouse 的 CSS audit 裡會輕鬆很多。

總結一下
效能優化真的是一場持久戰,不要指望一次搞定、一測就 100 分,因為每個專案都有不同的效能難關需要克服。
幾個我自己踩雷後得到的心得:
Lighthouse 分數 ≠ 使用體驗,但它還是一個不錯的參考。像我們這次就靠它找到一些資源過重的問題。
能省就省,字體、圖片、第三方腳本,全部都是能優化的地方。
善用 Next.js 提供的好工具,像是:
<Image>
幫你處理 lazy load + size 最佳化<Script strategy="lazyOnload">
控制 script 加載時機dynamic()
延遲載入非首要元件<Head>
處理 meta / SEO 等設定
組件設計階段就考慮 accessibility、標籤結構,這真的很重要,等到開發完再補救,通常會很痛苦
額外補充一些可考慮的手段:
頁面可以考慮用 SSG (Static Site Generation),讓內容先在 build 時就生成好,使用者打開網頁時不用等伺服器跑。
圖片、自託管字體、甚至 JS lib 都可以考慮搭配 CDN 或 edge-based hosting,效果非常有感。
可以搭配 VS Code 的 Import Cost 插件,幫你即時看到每個 import 進來的套件大小,在下載套件前,先考慮一番
使用
@next/bundle-analyzer
檢查你的 bundle 裡面塞了什麼,是否不小心 import 整包 lodash 或 date-fns,或是引用了專案非必要的套件
效能優化的細節實在太多了,很難在一篇文章裡全部講完。以後有機會我會再慢慢分享。
希望這篇能讓你在優化的路上少走一些冤枉路,哪怕只是 Lighthouse 多拿個 10 分,也絕對值得!
參考