你有沒有遇過這種情況:正準備點一個連結,圖片突然載入,整段文字往下一跳。結果手指點到旁邊的空白,只能在心裡默念:「謝謝,咖啡涼了。」
圖片最佳化不是單純把檔案壓到越小越好。面對 PageSpeed 和 Core Web Vitals,你通常要同時處理兩件事:
- LCP(載入速度):首圖什麼時候真正顯示出來?檔案太大、尺寸又不合適,下載自然會變慢。
- CLS(版面穩定度):圖片還沒載完之前,下面的內容會不會被往下推?沒有預留寬高,版面就容易跳動。
網站通常有很多圖片,像是產品截圖、比較表和規格圖。這篇先專心處理三件事:控制檔案大小、符合顯示寬度,以及預留圖片版面,並整理成可以直接照做的決策方式和範例。至於 LCP 的 fetchpriority 細節,留到之後再深入討論;這次先把「不要亂跳,也不要浪費頻寬」處理好。
目錄
先搞清楚:圖片最常造成兩種效能問題
靜態網站最常見的圖片問題,大概有這幾種:
- 圖沒有可預測的高度(CLS)
- hero/內文圖過肥,或丟超大原圖給小螢幕(LCP)
- 圖很多卻全靠手壓,漏寫
width/height
這篇會聚焦在:預留圖片尺寸、讓檔案大小和顯示寬度對得上,以及(可選的)Eleventy 圖片處理流程。字體、Cookie 橫幅和第三方腳本造成的 CLS/INP,先留到另一篇處理。一次解決一類問題,才不會改到最後連自己在修什麼都忘了。
以 2026 年的標準來看,Google 建議 CLS ≤ 0.1、LCP ≤ 2.5 秒。這裡看的是 CrUX 第 75 百分位的真實使用者資料,不是本機 Lighthouse 跑到 100 分就代表一切沒問題。想先了解 PageSpeed Insights 和欄位資料的差異,可以參考 PageSpeed Insights 與 Core Web Vitals 2026。
決策表一:width+height 還是 aspect-ratio?
白話一點說,瀏覽器在下載圖片前,最好先知道「這張圖大概會佔多高」,才不會把下面的內容推歪。HTML 的 width 和 height 會提供比例提示;再搭配 max-width: 100%; height: auto;,圖片在響應式縮放時,版面預留仍然有效。
可以把它想成搬家:先用膠帶在地板上標出沙發的位置,就算貨車晚一點到,也不會把其他家具推歪。圖片預留就是那捲膠帶。
| 情境 | 優先做法 | 為什麼 |
|---|---|---|
一般 <img>(hero、內文、產品圖) | HTML 真實像素 width + height + CSS max-width:100%; height:auto; | web.dev 推薦;瀏覽器自動算比例 |
| 比較表/圖牆:多張截圖要同一視覺框 | 外層容器 aspect-ratio: 16/9(或 4/3),圖用 object-fit: cover | 各圖比例不一也能先佔固定高 |
| iframe/YouTube 等嵌入 | 容器設 aspect-ratio 或固定高度 | 嵌入預設比例常怪,容易抖 |
| 還沒定最終檔案尺寸的占位 | 先用 CSS aspect-ratio,上線前補真實寬高 | 過渡方案 |
一般情況優先使用 HTML 寬高。 CSS 的 aspect-ratio 比較適合容器、嵌入內容或需要統一裁切比例的情境,不能完全取代每張圖片的寬高屬性。
可複製:一般內文/hero
<img
src="/img/product-dashboard.webp"
width="1200"
height="675"
alt="產品控制台介面截圖"
decoding="async"
/>/* 全站圖建議基底——不要寫 width: auto */
img {
max-width: 100%;
height: auto;
}width 和 height 要填的是圖片檔案本身的像素尺寸,不是圖片在螢幕上實際顯示的寬度。顯示大小交給 CSS 控制就好。
可複製:固定比例截圖容器
<figure class="shot">
<img
src="/img/compare-a.webp"
width="1600"
height="900"
alt="方案 A 設定畫面"
loading="lazy"
decoding="async"
/>
</figure>.shot {
aspect-ratio: 16 / 9;
width: 100%;
overflow: hidden;
background: #f2f2f2;
}
.shot img {
width: 100%;
height: 100%;
object-fit: cover;
max-width: none;
}常見錯誤(預留會失效)
| 錯誤 | 為什麼翻車 | 怎麼改 |
|---|---|---|
只有 max-width: 100%,沒有 width/height | 高度從 0 撐開 → 下面全跳 | 補真實 width+height |
CSS 寫了 img { width: auto; } | 蓋掉 HTML 寬度 hint,未載入變 0×0 | 刪掉 width: auto,保留 height: auto |
| width/height 比例填錯 | 先留錯高,圖載入再校正 → 仍算 CLS | 用檔案真實像素核對 |
| Lazy 圖沒預留 | 捲到才撐高 → post-load CLS | lazy 圖同樣要有寬高 |
5 分鐘快速檢查:全站搜尋 <img,確認每張圖都有寬高 → 檢查全域 CSS 沒有 width: auto → 用 PSI 或 Performance 面板查看 Layout Shifts。修完再喝一口咖啡,版面和心情都會穩定不少。
決策表二:檔案大小、顯示寬、WebP/AVIF
與其一直調低圖片品質,很多時候先符合顯示寬度更有效。手機上的內容欄可能只有 400px,卻載入一張 4000px 的原圖,像素數量差了不只一點點,下載和解碼都會變慢。這就像點了全家桶外送,最後只吃一塊雞塊。
| 顯示寬(約) | 建議產出寬(約,含 2× DPR) |
|---|---|
| 手機全寬 ~360–430px | 720–860px |
| 內容欄 ~640–720px | 1280–1440px |
| Hero 全寬桌面 ~1200px | 1200–1600px(超過 2000 通常浪費) |
站內檔案預算(實務目標,非官方硬門檻)
| 類型 | 目標大小 | 用法 |
|---|---|---|
| Hero/LCP 圖 | < 150KB | 優先保證首屏最大圖下載快 |
| 內文圖/截圖 | < 80KB | 長文多圖時累積流量很明顯 |
| 小縮圖/圖示 | < 20–30KB | 能用 SVG/CSS 就別用照片 |
這些數字不是 Google 訂下的官方門檻;Google 真正關心的是載入時間和版面位移。把圖片控制在合理大小,是讓使用慢速手機或 4G 網路的讀者更容易通過 LCP 的實用做法。
如果圖片超過預算,可以按照這個順序處理:先縮小寬度 → 改用 AVIF/WebP → 微調壓縮品質 → 裁掉不重要的背景。
格式怎麼選
| 條件 | 建議 |
|---|---|
| 靜態站、build 一次產檔 | AVIF + WebP + JPEG(<picture>) |
| 只想維護一種現代格式 | WebP + JPEG |
| UI 截圖、文字要銳利 | 別壓太狠;必要時略提高品質 |
| Logo/簡單圖示 | SVG 優先 |
<picture> 順序:先 AVIF,再 WebP,<img> 用 JPEG/PNG 兜底。瀏覽器會選第一個它吃得下的。
最小可用:srcset + sizes
<img
src="/img/guide-800.webp"
srcset="
/img/guide-400.webp 400w,
/img/guide-800.webp 800w,
/img/guide-1200.webp 1200w
"
sizes="(max-width: 768px) 100vw, 720px"
width="1200"
height="675"
alt="設定步驟示意"
loading="lazy"
decoding="async"
/>sizes 寫錯,瀏覽器常會下太大檔——等於你說「我只要一杯」,店員卻端來整壺。Hero/LCP 圖請用 loading="eager"(必要時加 fetchpriority="high"),別把首屏主角設成懶載入。
手動壓檔可用 Squoosh:先縮寬 → 試 AVIF/WebP → 符合 KB 預算 → 再寫真實寬高。
決策表三:手動補寬高,還是上 Eleventy 圖片管道?
圖片不多時,手動處理還可以接受;但如果網站每週都要放截圖,漏寫寬高或直接放出原始大圖,幾乎只是早晚的事。尤其是請 AI 產生 Markdown 時,它很愛順手塞一張超肥的 PNG。
如果你使用 Eleventy,可以考慮官方套件 @11ty/eleventy-img。建議先從 Image HTML Transform 開始,它能在建置時自動產生多種尺寸和現代圖片格式,也會幫你補上 width/height。
| 情境 | 建議 |
|---|---|
| 全站 < ~20 張圖、很少更新 | 手動縮圖 + 寫 width/height 可接受 |
| 部落格持續貼截圖/hero | HTML Transform(推薦) |
| 需要每圖不同裁切/藝術方向 | Image shortcode 或 WebC |
| 只要先救 CLS、暫不產多尺寸 | 至少手動補真實寬高 |
最小設定概念:
import { eleventyImageTransformPlugin } from "@11ty/eleventy-img";
export default function (eleventyConfig) {
eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
formats: ["avif", "webp", "jpeg"],
widths: [400, 800, 1200, "auto"],
htmlOptions: {
imgAttributes: {
loading: "lazy",
decoding: "async",
sizes: "(max-width: 768px) 100vw, 720px",
},
},
});
}注意:Transform 預設通常會使用 loading: "lazy"。Hero/LCP 圖要改成 eager,必要時再加上 fetchpriority="high"。如果產生了多種寬度,也要記得設定合理的 sizes,否則瀏覽器可能把它當成 100vw,下載比實際需要更大的圖片。
建議按照這個順序導入:先檢查全站圖片並補上寬高,先把 CLS 穩住 → 再開啟 Transform,抽查建置結果 → 新文章只放合理尺寸的原圖。不要再丟一張 8000px 的巨圖,然後安慰自己「以後可能用得到」。
Hugo/Astro 也有對應圖片管道;原則相同:建置時產對的尺寸 + 寫上寬高。
推薦工具/資源
| 需求 | 工具/做法 | 適合誰 |
|---|---|---|
| 手動壓到 KB 目標 | Squoosh、ImageOptim | 圖少、先驗流程 |
| Eleventy 自動多尺寸+寬高 | @11ty/eleventy-img Transform | 持續發文的靜態站 |
| 驗收欄位資料 | GSC → 體驗 → Core Web Vitals、PageSpeed Insights | 修完要對真實使用者分數 |
| 圖都瘦了但全站仍慢(TTFB/憑證) | ZeroSSL 檢查/更新 HTTPS 憑證鏈 | 自架或憑證快到期、混合內容警告時 |
HTTPS 正常、憑證鏈完整,才不會在傳輸層又多出一個體驗問題。圖片預留和壓縮檔案,主要解決的是前端 CLS 與下載量;HTTPS 憑證則是另一個層次,兩者最好分開檢查。憑證設定可以參考站內的 ZeroSSL 教學。
結語:圖片最佳化,就是別讓 CLS 亂跳、也別拖慢下載
- 每張
<img>補真實width+height(或容器aspect-ratio);刪掉會搞壞預留的width: auto - 顯示寬符合再壓檔:hero 瞄準 < 150KB、內文 < 80KB;優先 AVIF/WebP
- 圖一多就上 build 管道(Eleventy 用
eleventy-img),hero 記得覆寫勿 lazy - 用 GSC/PSI 驗收;欄位資料大約看 28 天滾動
下一步:先替全站圖片補齊寬高,並檢查 Hero 和內文圖片是否符合檔案預算。如果建置產物都沒問題,但 TTFB 仍然偏高,或憑證出現警告,再用 ZeroSSL 把 HTTPS 和憑證鏈處理好,最後回到 GSC 對照體驗資料。檢查完,再來一杯咖啡。

