Coolkid mascot CoolkidLab Build in Public. Level up together.
首頁新手教學免費工具AI 新聞GitHub 精選陪跑服務關於

SEO 菜鳥成長史 · #2

PageSpeed 效能 67 → 93:三輪優化全紀錄

閱讀
摘要

PageSpeed 分數太低怎麼優化?非工程師的靜態站從 67 分修到 93 分,只動了三件事,壓圖片(WebP 省 97%)、字型改成 font-display: optional、修版面位移(CLS 0.336 降到 0.05)。每輪只改一個變因,總共約 1.5 小時。

GSC 等不到資料的這幾天,我先跑去玩 PageSpeed Insights。

第一次跑完就直接被打臉。

效能 67 分(橘燈),最大內容繪製(LCP)19.8 秒。Google 自己定的標準是 2.5 秒。我超標將近 8 倍。

這篇紀錄我怎麼把效能從 67 衝到 93,LCP 從 19.8 秒降到 2.3 秒,CLS 從 0.336 修到 0.05 以下。

總共三輪,每一輪只修一個東西。

1. 為什麼這篇值得寫

PageSpeed 的教學文章一抓一大把,但大部分都是「給工程師看的清單」:

我這種非工程師背景的,看了只會更慌。

實際上一個普通的靜態網站,九成的問題就集中在三件事,圖片太大、字型載得慢、版面在跳。

把這三件處理完,分數會從 60 多直接跳到 90 以上。

先講官方的標準訂在哪裡。Google Core Web Vitals 官方標準把「良好」定義成 LCP 不超過 2.5 秒,CLS 不超過 0.1,互動回應(INP)不超過 200 毫秒,取的是所有造訪的第 75 個百分位。

下面三輪優化追的就是這條線。

2. 為什麼圖片是 PageSpeed 最大兇手?(67 → 78)

看到 67 分,第一反應是「我程式碼是不是哪裡寫爛了」。冷靜下來打開 assets 資料夾:

portrait-pixel.png   1907 KB
mascot.png           1627 KB
logo.png             1668 KB

問題一眼就看得出來。三張 1024×1024 以上的 PNG,但網站實際只顯示 240×240 或更小。

這就像下單買 1000 股,結果只成交 100 股,另外 900 股的錢全部白付。

修法用 Pillow 寫 10 行 Python:

from PIL import Image
img = Image.open('assets/portrait-pixel.png')
img.resize((480, 480), Image.LANCZOS).save(
    'assets/portrait-pixel.webp',
    format='WEBP', quality=85, method=6
)

結果:

順手做了三件事讓 hero 圖更早顯示:

  1. <picture> 包 WebP source + PNG fallback(舊瀏覽器仍可用)
  2. Hero img 加 fetchpriority='high' + decoding='async'
  3. 首頁 <head> 加 <link rel='preload'> 提前下載

再跑一次。效能 67 變成 78,LCP 從 19.8 秒降到 2.3 秒,亮綠燈了。

但總分還是沒有過 90。

3. CLS 0.336 修不到 0.1 怎麼辦?(78 → 93)

圖片修完,下一個紅燈是 CLS(Cumulative Layout Shift)0.336。標準是 < 0.1。

CLS 就是「畫面亂跳指數」。頁面載入的時候東西還在動,使用者體驗會被扣分。

我這站有兩個地方在跳。

(1)Mascot 圖片屬性跟 CSS 對不起來

img 標籤寫的是 width=32 height=32,但 CSS 後面又寫 width:84px height:84px。

瀏覽器會先照 img 屬性畫一個 32×32 的位置,等 CSS 載入後再撐成 84×84,整列導覽跟著跳一下。

修法:把 img 屬性改成跟 CSS 一致的 84×84。順便重新產 168×168 的 mascot 給 retina 顯示用。

(2)Press Start 2P 字型用 swap 模式

我整站用 Press Start 2P 這個像素字體,從 Google Fonts 抓的。

預設模式是 font-display: swap,先用系統字體畫出來,等 web font 載完再換過去。

換的那一瞬間整個版面重排,因為像素字的寬度跟一般字差很多。CLS 就是這樣衝上去的。

修法很簡單,URL 一個字改掉:

// 改前
fonts.googleapis.com/css?family=Press+Start+2P&display=swap

// 改後
fonts.googleapis.com/css?family=Press+Start+2P&display=optional

optional 模式的意思是,給瀏覽器 100 毫秒去載字型,超過就一律改用備用字體,而且整次造訪都不再換回來。

所以第一次進來的人可能看到中文備用字體,第二次以後字型已經在快取裡,就會正常顯示。

代價是第一次的視覺體驗略差。但 CLS 直接歸零。

再跑一次。效能 78 變 93,CLS 從 0.336 掉到 0.05 以下。

三個主要指標全部亮綠燈。

4. 無障礙卡在 89 怎麼補到 100?(色彩對比)

效能 93 之後,唯一還沒過 90 的是無障礙,89 分。

Lighthouse 的無障礙檢測主要看三件事,色彩對比、語意化標籤、ARIA 屬性。

我的問題集中在色彩對比。網頁無障礙標準(WCAG AA)要求文字跟背景的對比度至少 4.5 比 1。寫一段 Python 算一下:

def luminance(hex_color):
    # ...省略
    return 0.2126*adj(r) + 0.7152*adj(g) + 0.0722*adj(b)

def ratio(c1, c2):
    l1, l2 = luminance(c1), luminance(c2)
    return (max(l1,l2)+0.05) / (min(l1,l2)+0.05)

結果發現我用的 --text-mute 顏色全部不及格:

情境原色對比度新色
深色主題 mute 文字#6c757d3.29 ❌#9ba3ab
淺色主題 mute 文字#868e963.13 ❌#666f76
白卡片上 mute 文字#6c757d4.45 ❌#666f76

改三個 hex 字串,重新 build。預期分數 89 → 95+,理論上沒其他問題就會直接到 100。

5. 最終戰績

指標起點終點
效能67 ❌93 ✅
LCP19.8 秒 ❌2.3 秒 ✅
CLS0.336 ❌< 0.1 ✅
無障礙8995+ ✅
SEO100 ✅100 ✅
最佳做法100 ✅100 ✅

6. 我從這個過程學到什麼

三輪下來我最大的收穫,不是分數本身。是「先看數字、再修」這個流程。

第一次看到紅字,我會想「整個專案是不是要重寫」。第二次學會了問:

這跟我做交易學到的東西一樣。不是看到價格往下就砍倉,是先讀數據,找出原因,再決定要不要動。

一次只動一個變因,動完看結果,再決定下一個。

7. PageSpeed 卡在 60-80,該按什麼順序修?(4 步驟 checklist)

如果你的網站 PageSpeed 也卡在 60-80,按這個順序走:

  1. 打開 assets 看圖片大小:超過 200KB 的全部壓縮。WebP 通常能壓掉 90%。
  2. Hero 圖(首頁第一眼看到的圖)加 fetchpriority='high' + <link rel='preload'>
  3. 用非系統字體?把 font-display 從 swap 改成 optional,CLS 直接歸零。
  4. 用 Lighthouse 報告裡的「待改善項目」逐項點開,每項都會告訴你修哪裡。

這個檢查清單我自己跑完,從 67 到 93 大概花 1.5 小時。包括寫 Pillow 腳本、查 font-display 文件、跑三次 PageSpeed 驗證。

8. 下一步

PageSpeed 跑完,網站大致算是「Google 看了會點頭」的狀態。

但這只是一張門票。真正的搜尋排名還要靠內容、內鏈、外部連結,還有長期穩定的累積。

白老鼠實驗下一篇 #3 會回到 GSC:經過一週後,sitemap 到底抓了沒、哪幾頁先進索引、第一個搜尋查詢長什麼樣。

效能這條線後來還有續集。三個月後同一個站又從 79 衝到 89,那次處理的是關鍵路徑跟阻塞渲染,寫在 #11 PageSpeed 79 → 89:阻塞渲染的關鍵路徑優化

名詞解釋

PageSpeed Insights
Google 提供的免費網站速度體檢工具,輸入網址就給 0-100 分跟改善建議。本文的 67 → 93 講的就是這個分數。
Lighthouse
PageSpeed 背後的檢測引擎,Chrome 瀏覽器也內建。報告會逐項列出「哪裡慢、該修什麼」,照著修就好,不用猜。
最大內容繪製(LCP, Largest Contentful Paint)
頁面上「最大那塊內容」(通常是首圖或大標題)出現所需的秒數。Google 標準 ≤ 2.5 秒,本站曾經 19.8 秒。
累積版面位移(CLS, Cumulative Layout Shift)
畫面亂跳指數:載入過程版面移動越多、分數越高。標準 < 0.1,常見元兇是圖片沒寫尺寸跟字型替換。
互動回應(INP, Interaction to Next Paint)
從你點按鈕到畫面有反應的延遲毫秒數,標準 ≤ 200 毫秒。跟 LCP、CLS 合稱 Google 三大網站體驗指標(Core Web Vitals)。
WebP
Google 推的圖片格式,同樣畫質下檔案比 PNG / JPG 小很多 — 本文實測一張 1907 KB 的 PNG 壓成 56 KB,省 97%。
字型顯示策略(font-display)
告訴瀏覽器「網路字型還沒載好時怎麼辦」的 CSS 設定。swap = 先用備用字體再換(會跳版);optional = 100 毫秒內載不到就整次都用備用字體(不跳版)。
備用字體(fallback font)
指定字型載不到時,瀏覽器改用的替代字體。例如本站 pixel 字型載不到時,改用系統內建的微軟正黑體。
無障礙(accessibility)
讓視力不佳、不便操作的人也能順利使用網站的設計標準。WCAG AA 是國際標準的中間等級,要求文字與背景對比度 ≥ 4.5:1。
預載(preload)
在網頁開頭先宣告「這個檔案很重要,先下載」。把首圖設成預載,使用者第一眼的畫面就會更早出現。
Pillow
Python 程式語言的圖片處理工具庫,幾行程式就能批次縮圖、轉檔。本文壓圖的 10 行腳本就是用它。

全站名詞表 · 161 條 →

看完這篇之前先確認:

適合你
  • 想把 Lighthouse 紅燈調綠的個人站
  • 不想花錢上 CDN / 付費圖床的人
  • 願意一刀只改一個變因再測的人
不適合
  • 已經 90 分以上的成熟站
  • 主要靠付費廣告流量的電商
  • 企業級站(需另一套 perf 架構)

不想錯過 Lab 的新文章?
訂閱後有新文章上線,就寄信通知你,
點有興趣的進來看就好。

填 email 就完成訂閱(信由 Substack 代寄)、隨時取消、不轉賣 email。

如果內容對你有用就太好了
隨喜斗內

Buy Me a Coffee at ko-fi.com
NEXT CHAPTER ▸ #0 GSC(Google Search Console)是什麼?5 分鐘看懂

相關閱讀

這篇背後的真實開發過程記錄在 Build Log。 搜尋標籤:pagespeedlcpclsa11y

本篇為個人學習與實驗紀錄。PageSpeed Insights 演算法持續變動,本文方法不保證在你的網站產生相同效果,請依自身網站狀況實驗驗證。本站不接 YMYL 高風險站、不做 PBN、不做品牌矩陣 SEO。

← 回 SEO 菜鳥成長史

⚠ 本站所有內容僅供教育與研究用途,不構成投資建議,不保證任何獲利。投資有風險,使用者須自行判斷並承擔結果。
TAO 道 · Hikari Zen YouTube ↗
音樂透過 YouTube 播放
♪ TAO 道 · Hikari Zen — Japanese Zen Music(YouTube)