為什麼要用 next/image 而不是原生 ![]()
Next.js 的 元件(來自 next/image)比原生 HTML 多做了這些事:
- 自動格式轉換:根據瀏覽器支援,自動把圖片轉為 WebP 或 AVIF 格式(比 JPEG 小 25-50%)
- 自動調整尺寸:根據裝置的實際像素密度(Retina, 2x, 3x)提供適當大小的圖片
- Lazy Loading 預設開啟:視窗外的圖片不會立即載入
- 防止 CLS:要求提供寬高,預留圖片空間,避免頁面載入時的版面跳動
- 內建 Blur 預覽:可以在圖片載入前顯示模糊的佔位圖(placeholder="blur")
這些都是 Core Web Vitals 的直接改善點,幾乎不需要額外設定就能在發布後看到效能提升。
基本使用語法
import Image from 'next/image'
// 本地圖片(Next.js 會自動取得寬高)
import heroImg from '@/public/images/hero.jpg'
<Image
src={heroImg}
alt="首頁 Hero 圖片"
placeholder="blur" // 自動產生 blurDataURL
/>
// 遠端圖片(需要指定寬高)
<Image
src="https://example.com/photo.jpg"
alt="描述文字"
width={800}
height={600}
sizes="(max-width: 768px) 100vw, 800px"
/>
最重要的參數:priority 和 sizes
priority:Hero 圖片必須設定
預設是 lazy loading。但 Hero 圖片或頁面上第一個大型可見圖片,不應該 lazy load——這樣做反而會讓 LCP(最大內容繪製)指標變差。
<Image
src={heroImg}
alt="品牌形象圖"
priority // 告訴 Next.js 這張圖要優先載入,加入 preload
fill
className="object-cover"
/>
經驗法則:第一屏(Above the Fold) 內可見的圖片都加 priority,其他圖片讓 lazy loading 處理。
sizes:告訴瀏覽器不同螢幕寬度下的圖片顯示尺寸
sizes 是最常被忽略但非常重要的參數。它告訴瀏覽器在下載圖片之前,這張圖在不同螢幕寬度下會佔多大空間,讓瀏覽器選擇最合適的圖片解析度。
// 全寬圖片(100% 螢幕寬)
<Image
src={bannerImg}
alt="橫幅圖片"
fill
sizes="100vw"
/>
// 兩欄 grid 佈局(桌機佔一半,手機全寬)
<Image
src={cardImg}
alt="卡片圖片"
width={600}
height={400}
sizes="(max-width: 768px) 100vw, 50vw"
/>
// 三欄 grid(桌機佔三分之一,平板佔一半,手機全寬)
<Image
src={portfolioImg}
alt="作品集圖片"
width={400}
height={300}
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"
/>
沒有設定 sizes 時,Next.js 預設假設圖片是 100vw(全螢幕寬),會讓手機也下載桌機尺寸的圖片,浪費頻寬降低速度。
fill 模式:讓圖片填滿父容器
當你不知道圖片的確切尺寸,或需要圖片填滿容器(如 Hero 背景圖、作品集封面)時,使用 fill 模式:
<div className="relative w-full h-[400px]">
<Image
src={coverImg}
alt="封面圖"
fill
className="object-cover object-center"
sizes="100vw"
/>
</div>
父容器必須設定 position: relative(Tailwind 的 relative),圖片才能正確定位。
遠端圖片的網域白名單設定
當 src 是外部 URL 時,需要在 next.config.ts 設定允許的網域,否則 Next.js 會拒絕優化這些圖片(防止 SSRF 攻擊):
// next.config.ts
const nextConfig: NextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'your-cdn.com',
pathname: '/images/**',
},
{
protocol: 'https',
hostname: '**.supabase.co', // 萬用字元支援子網域
},
],
},
}
alt text:SEO 和無障礙都需要
每張有意義的圖片都需要描述性的 alt 文字:
// 不好的做法
<Image src={logo} alt="logo" />
<Image src={photo} alt="image" />
// 好的做法
<Image src={logo} alt="SimpleCreative 簡創數位工作室" />
<Image src={teamPhoto} alt="SimpleCreative 設計師在工作室進行設計稿審閱" />
純裝飾性的圖片(背景圖案、抽象裝飾)使用空 alt:alt=""
常見問題排解
問題:圖片載入後版面跳動(CLS 高)
原因:沒有提供 width 和 height(或沒有使用 fill 模式的父容器)
解法:明確提供 width/height 或使用父容器 + fill 模式
問題:Hero 圖片出現在 LCP 問題列表
原因:Hero 圖片沒有加 priority,被 lazy loading 延遲
解法:加上 priority prop
問題:行動裝置下載了過大的圖片
原因:沒有設定 sizes prop
解法:根據實際佈局設定正確的 sizes
正確使用 Next.js Image 元件,通常是最快能看到 PageSpeed Insights 分數提升的單一改動。