返回部落格
技術科普

2026 網站圖片載入太慢?工程師必備 8 項效能優化完整策略

發佈於15 min read
分享文章

圖片是網頁效能的頭號瓶頸

從技術實現來看,圖片佔據了現代網頁總傳輸量的壓倒性比例。根據 HTTP Archive 2025 年 12 月的統計數據,桌面版網頁的中位數總大小約為 2,312 KB,其中圖片佔了約 1,026 KB,接近 44.4%。行動版的比例更高,圖片佔總傳輸量約 47%。

這代表一件事:如果你只能優化網站的一個環節,選圖片就對了。

更關鍵的是,圖片直接影響 Google 的 Core Web Vitals 指標,特別是 LCP(Largest Contentful Paint)。根據 Google 的 CrUX 報告,超過 70% 的網頁 LCP 元素是圖片或帶有背景圖片的區塊。LCP 超過 2.5 秒就會被判定為「需要改善」,超過 4 秒則是「差」,直接影響 SEO 排名。

接下來我會從架構層面逐一拆解圖片優化的每個環節。

一個真實踩雷案例:LCP 從 1.8s 衝到 6.2s

先說結論:去年我處理過一個客戶案子,LCP 從綠區(1.8s)暴衝到紅區(6.2s),只改了一張首頁 hero 圖。我一開始以為是 JS bundle 炸了,debug 了三天才發現——新設計師丟了一張 4.5MB 的 1920×1080 PNG 上首頁,沒壓、沒 loading 屬性、沒 fetchpriority,也沒走 CDN。實測下來,光這一張圖就把 LCP 拖垮。

後來三件事做完,LCP 就回到 1.9s:

  1. PNG 轉 WebP,壓到 180KB(縮了 96%)
  2. 加 fetchpriority="high" 與 <link rel="preload">
  3. 把圖推上 Cloudflare R2 + Transform Rules 自動 AVIF fallback

這個坑很多人踩過。說穿了,首頁 hero 圖就是 LCP 的命門,任何一個環節沒做對,整張 Core Web Vitals 報告都會翻紅。下面每個章節都是從這類案子裡萃取出來的,不是抄文件。

Lazy Loading:延遲載入非可視區域圖片

原生 HTML 方案

最簡單的做法是使用瀏覽器原生的 loading="lazy" 屬性:

<img src="photo.webp" loading="lazy" alt="範例圖片" width="800" height="600">

底層原理是瀏覽器會在圖片進入視窗(viewport)附近時才發出 HTTP 請求。Chrome 的實作是在距離視窗約 1250px(桌面)或 2500px(慢速網路)時開始載入,確保使用者滾動到圖片位置時已經載入完成。

注意:首屏可見的圖片(Above the Fold)不應該設定 lazy loading,否則會延遲 LCP。首屏圖片應該用 loading="eager"(預設值)並加上 fetchpriority="high" 提升優先級。

JavaScript 方案:Intersection Observer

如果需要更細粒度的控制,可以使用 Intersection Observer API:

const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;
      observer.unobserve(img);
    }
  });
}, { rootMargin: '200px' });

document.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));

這個方案的好處是可以自訂觸發距離(rootMargin)、搭配淡入動畫、或在載入前先顯示低解析度佔位圖(LQIP)。

兩種方案比較

比較項目 原生 loading="lazy" Intersection Observer
實作複雜度 極低(一個屬性) 中等(需寫 JS)
瀏覽器支援 95%+(2026 年) 97%+
觸發距離可控 否(瀏覽器決定) 是(rootMargin)
LQIP 佔位圖 不支援 支援
SEO 友善 是(瀏覽器原生) 需確保 noscript 備援
首屏誤用風險 有(需手動排除) 可程式化排除

建議策略:大多數場景用原生方案即可,只在需要 LQIP 或精細控制時才用 Intersection Observer。

Responsive Images:讓裝置只下載需要的尺寸

一張 3000px 寬的英雄圖片,在手機上只需要 750px 寬。如果不做 responsive images,手機使用者會白白下載 4 倍大的圖片。

srcset + sizes 實作

<img
  srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w, hero-1600.webp 1600w"
  sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 800px"
  src="hero-800.webp"
  alt="首頁橫幅"
>

瀏覽器會根據裝置的視窗寬度和像素密度,從 srcset 中選擇最適合的圖片。sizes 告訴瀏覽器這張圖片在不同斷點下會佔多寬,讓它做出更精準的選擇。

<picture> 元素:格式與藝術方向控制

<picture>
  <source srcset="hero.avif" type="image/avif">
  <source srcset="hero.webp" type="image/webp">
  <img src="hero.jpg" alt="首頁橫幅">
</picture>

<picture> 讓你可以針對不同瀏覽器提供不同格式,優先使用壓縮率最高的格式,自動 fallback 到相容格式。

圖片格式選擇策略

格式選擇直接影響檔案大小和畫質。以下是基於實測數據的比較(測試條件:同一張 1920x1080 照片,視覺品質相當):

格式 典型檔案大小 瀏覽器支援 透明度 動畫 適用場景
JPEG 基準 100% 100% 否 否 照片(最大相容性)
WebP 約 JPEG 的 70% 97%+ 是 是 照片與圖形(推薦預設)
AVIF 約 JPEG 的 50% 92%+ 是 是 照片(最佳壓縮率)
PNG JPEG 的 300-500% 100% 是 否 需要透明度的圖形
SVG 極小(向量) 100% 是 是 圖示、Logo、圖表

建議策略:優先提供 AVIF → WebP → JPEG 的漸進式降級。用 <picture> 元素讓瀏覽器自動選擇最佳格式。想更深入了解三個現代格式的取捨與瀏覽器支援現況,可以參考 WebP/AVIF/JPEG XL 格式比較。

CDN 與快取策略

CDN 的核心價值

圖片從台灣的伺服器傳到美國使用者,物理距離約 12,000 公里,光纖中光速傳播的延遲就有約 40ms(單程)。加上 TCP 握手、TLS 交換、HTTP 請求回應,一張圖片的 TTFB(Time To First Byte)可能超過 200ms。

CDN 透過全球邊緣節點快取圖片,讓使用者從最近的節點取得資源。一個好的 CDN 可以將 TTFB 從 200ms+ 降到 20-50ms。

快取標頭設定

Cache-Control: public, max-age=31536000, immutable

圖片通常不會變動,設定一年的快取時間搭配 immutable 標記,告訴瀏覽器不需要重新驗證。如果圖片需要更新,透過更換檔名(加 hash)來強制失效。

圖片 CDN 服務

像 Cloudflare Images、Imgix、Cloudinary 這類圖片 CDN 服務,除了基本的 CDN 分發外,還提供:

  • 即時格式轉換(根據 Accept 標頭自動選擇 AVIF/WebP/JPEG)
  • 即時尺寸調整(透過 URL 參數指定寬高)
  • 自動品質優化(根據網路速度調整壓縮率)

圖片壓縮管線

從技術架構來看,一個完整的圖片壓縮管線應該包含以下環節:

  1. 上傳時壓縮:使用 Sharp(Node.js)或 Pillow(Python)在伺服器端壓縮
  2. 多尺寸生成:為每張圖片生成 3-5 個尺寸變體(400w、800w、1200w、1600w、原圖)
  3. 多格式轉換:為每個尺寸生成 AVIF、WebP、JPEG 三種格式
  4. 品質參數調校:JPEG quality 75-85、WebP quality 75-80、AVIF quality 60-70
  5. 元資料清除:移除 EXIF 資料減少檔案大小(同時保護隱私)

以一張 1920x1080 的照片為例,經過完整管線後,手機使用者實際下載的可能是一張 400w 的 AVIF 圖片,檔案大小從原始的 2MB 降到約 30KB,減少了 98.5% 的傳輸量。

Core Web Vitals 的影響與優化目標

LCP(Largest Contentful Paint)

LCP 衡量最大可見元素的繪製時間。對於以圖片為 LCP 元素的頁面:

  • 好:≤ 2.5 秒
  • 需要改善:2.5 - 4 秒
  • 差:> 4 秒

優化首屏圖片的具體做法:

  1. 使用 fetchpriority="high" 提升首屏圖片的下載優先級
  2. 使用 <link rel="preload"> 預載入 LCP 圖片
  3. 避免對首屏圖片使用 lazy loading
  4. 確保首屏圖片的 CDN 快取命中率

CLS(Cumulative Layout Shift)

圖片載入時如果沒有預留空間,會造成版面跳動。解法很簡單:永遠在 <img> 標籤上指定 width 和 height 屬性,讓瀏覽器在圖片載入前就能計算出正確的 aspect ratio。

<img src="photo.webp" width="800" height="600" alt="範例">

圖片效能優化檢查清單

在上線前逐項確認:

  • 首屏圖片設定 fetchpriority="high",非首屏設定 loading="lazy"
  • 所有 <img> 標籤都有 width 和 height 屬性
  • 使用 <picture> 提供 AVIF/WebP/JPEG 漸進式降級
  • 使用 srcset + sizes 提供多尺寸變體
  • 圖片經過壓縮,JPEG quality 75-85、WebP quality 75-80
  • CDN 已啟用,快取標頭設定正確(max-age=31536000, immutable)
  • EXIF 元資料已移除
  • LCP 圖片已用 <link rel="preload"> 預載入
  • 在 PageSpeed Insights 上 LCP ≤ 2.5 秒

圖片託管服務的角色

如果你不想自己建構完整的圖片壓縮管線和 CDN 架構,使用專業的圖片託管服務是一個務實的選擇。

以 lpic.cc 為例,它提供免註冊的圖片上傳、CDN 全球分發、以及密碼保護功能。對於部落格作者或小型網站來說,可以省去自建圖片基礎設施的成本。不過要注意,lpic.cc 目前不提供 API 串接和即時尺寸調整功能,如果你的專案需要程式化批次上傳或動態裁切,可能需要搭配 Cloudinary、Imgix 等專業圖片 CDN 服務。

常見問題 FAQ

Q1:Lazy loading 會影響 SEO 嗎?

不會。Google 的爬蟲(Googlebot)會執行 JavaScript 並模擬滾動,可以正確索引使用 loading="lazy" 的圖片。但如果你使用自訂的 JavaScript lazy loading 方案,建議加上 <noscript> 標籤作為備援,確保搜尋引擎能抓到圖片 URL。

Q2:WebP 和 AVIF 我該優先用哪個?

從壓縮率來看 AVIF 勝出(比 JPEG 小約 50%),但 AVIF 的編碼速度較慢,不適合即時轉換場景。建議策略是用 <picture> 同時提供兩者,讓瀏覽器自動選擇。如果只能選一個,WebP 的瀏覽器支援度更高(97% vs 92%),是更安全的選擇。

Q3:圖片 CDN 值得花錢嗎?

取決於你的流量規模。如果月流量在 10 萬 PV 以下,Cloudflare 的免費方案(含基本 CDN)通常就夠用。超過這個規模,專業圖片 CDN 如 Imgix 或 Cloudinary 的自動格式轉換和尺寸調整功能可以顯著減少頻寬成本,長期來看反而省錢。

Q4:圖片壓縮會不會影響畫質?

有損壓縮一定會影響畫質,但在合理的品質參數下(JPEG 75-85、WebP 75-80),人眼幾乎無法察覺差異。建議用 SSIM(結構相似性指標)來量化評估:SSIM > 0.95 時,大多數使用者無法區分壓縮前後的差異。實際各家圖床壓到多低,我整理在 SSIM 圖床壓縮品質實測 有量化對照。

Q5:我的網站已經用了 CDN,還需要做圖片優化嗎?

需要。CDN 只解決了「傳輸距離」的問題,不解決「傳輸量」的問題。一張未優化的 5MB 圖片,即使透過 CDN 從最近的節點傳輸,仍然需要 5MB 的頻寬。格式轉換、尺寸適配、壓縮這些優化手段可以把傳輸量減少 80-95%,效果遠大於單純使用 CDN。實際上傳環節的網路瓶頸與 CDN 差異可以看 圖床上傳速度實測 的測速數據。

參考資料

#網站效能#圖片優化#lazy loading#responsive images#CDN#Core Web Vitals
H

作者

Harvey Zhang

共同創辦人兼 CTO

後端工程師出身,從系統架構角度深度解析圖片託管服務的技術實現。