Image (舊版)
從 Next.js 13 開始,next/image
元件經過重寫以提升效能和開發者體驗。為了提供向後相容的升級方案,舊版 next/image
已更名為 next/legacy/image
。
檢視新版 next/image
API 參考文件
比較
與 next/legacy/image
相比,新版 next/image
元件有以下變更:
- 移除
<img>
周圍的<span>
包裝,改用原生的計算寬高比 - 新增對標準
style
prop 的支援- 移除
layout
prop,改用style
或className
- 移除
objectFit
prop,改用style
或className
- 移除
objectPosition
prop,改用style
或className
- 移除
- 移除
IntersectionObserver
實作,改用原生延遲載入- 移除
lazyBoundary
prop,因為沒有原生等效項 - 移除
lazyRoot
prop,因為沒有原生等效項
- 移除
- 移除
loader
配置,改用loader
prop - 將
alt
prop 從可選改為必填 - 變更
onLoadingComplete
回調函式,使其接收<img>
元素的參考
必要屬性
<Image />
元件需要以下屬性。
src
必須是以下其中一項:
使用預設 loader 時,還需考慮以下來源圖片情況:
- 當 src 是外部 URL 時,必須配置 remotePatterns
- 當 src 是動畫圖片或非已知格式 (JPEG、PNG、WebP、AVIF、GIF、TIFF) 時,圖片將按原樣提供
- 當 src 是 SVG 格式時,除非啟用
unoptimized
或dangerouslyAllowSVG
,否則將被阻止
width
width
屬性可表示 渲染 寬度或 原始 寬度(像素),取決於 layout
和 sizes
屬性。
使用 layout="intrinsic"
或 layout="fixed"
時,width
屬性表示 渲染 寬度(像素),因此會影響圖片顯示的大小。
使用 layout="responsive"
或 layout="fill"
時,width
屬性表示 原始 寬度(像素),因此只會影響寬高比。
width
屬性是必填的,除非是靜態匯入的圖片或使用 layout="fill"
的情況。
height
height
屬性可表示 渲染 高度或 原始 高度(像素),取決於 layout
和 sizes
屬性。
使用 layout="intrinsic"
或 layout="fixed"
時,height
屬性表示 渲染 高度(像素),因此會影響圖片顯示的大小。
使用 layout="responsive"
或 layout="fill"
時,height
屬性表示 原始 高度(像素),因此只會影響寬高比。
height
屬性是必填的,除非是靜態匯入的圖片或使用 layout="fill"
的情況。
可選屬性
<Image />
元件接受許多額外屬性。本節描述 Image 元件最常用的屬性。更多較少使用的屬性詳情請參閱進階屬性一節。
layout
圖片在視口大小變化時的佈局行為。
layout | 行為 | srcSet | sizes | 有包裝和尺寸調整器 |
---|---|---|---|---|
intrinsic (預設) | 縮小以適應容器寬度,最大不超過圖片原始尺寸 | 1x , 2x (基於 imageSizes) | N/A | 是 |
fixed | 嚴格按照 width 和 height 設定尺寸 | 1x , 2x (基於 imageSizes) | N/A | 是 |
responsive | 縮放以適應容器寬度 | 640w , 750w , ... 2048w , 3840w (基於 imageSizes 和 deviceSizes) | 100vw | 是 |
fill | 在 X 和 Y 軸上延伸以填滿容器 | 640w , 750w , ... 2048w , 3840w (基於 imageSizes 和 deviceSizes) | 100vw | 是 |
- 演示
intrinsic
佈局 (預設)- 當
intrinsic
時,圖片會針對較小的視口縮小尺寸,但對較大的視口保持原始尺寸。
- 當
- 演示
fixed
佈局- 當
fixed
時,圖片尺寸不會隨視口變化而改變(無響應性),類似於原生的img
元素。
- 當
- 演示
responsive
佈局- 當
responsive
時,圖片會針對較小的視口縮小尺寸,並針對較大的視口放大尺寸。 - 確保父元素在樣式表中使用
display: block
。
- 當
- 演示
fill
佈局- 當
fill
時,圖片會在寬度和高度上延伸以符合父元素的尺寸,前提是父元素是相對定位。 - 這通常與
objectFit
屬性搭配使用。 - 確保父元素在樣式表中具有
position: relative
。
- 當
- 演示背景圖片
loader
用於解析 URL 的自訂函式。在 Image 元件上設定 loader prop 會覆蓋 next.config.js
的 images
區段中定義的預設 loader。
loader
是一個函式,根據以下參數返回圖片的 URL 字串:
以下是使用自訂 loader 的範例:
import Image from 'next/legacy/image'
const myLoader = ({ src, width, quality }) => {
return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}
const MyImage = (props) => {
return (
<Image
loader={myLoader}
src="me.png"
alt="Picture of the author"
width={500}
height={500}
/>
)
}
sizes
一個字串,提供有關圖片在不同斷點下寬度的資訊。sizes
的值會極大影響使用 layout="responsive"
或 layout="fill"
的圖片效能。對於使用 layout="intrinsic"
或 layout="fixed"
的圖片,此屬性會被忽略。
sizes
屬性在圖片效能方面有兩個重要作用:
首先,瀏覽器使用 sizes
的值來決定從 next/legacy/image
自動生成的來源集中下載哪個尺寸的圖片。當瀏覽器選擇時,它還不知道圖片在頁面上的實際大小,因此會選擇與視口相同或更大的圖片。sizes
屬性允許您告訴瀏覽器圖片實際上會比全螢幕小。如果不指定 sizes
值,則預設使用 100vw
(全螢幕寬度)。
其次,sizes
值會被解析並用於修剪自動建立的來源集中的值。如果 sizes
屬性包含如 50vw
這樣的值(表示視口寬度的百分比),則來源集會被修剪,以排除任何可能永遠不需要的過小值。
例如,如果您知道您的樣式會導致圖片在行動裝置上全寬顯示,在平板電腦上以 2 欄佈局顯示,在桌面上以 3 欄佈局顯示,則應包含如下所示的 sizes 屬性:
import Image from 'next/legacy/image'
const Example = () => (
<div className="grid-element">
<Image
src="/example.png"
layout="fill"
sizes="(max-width: 768px) 100vw,
(max-width: 1200px) 50vw,
33vw"
/>
</div>
)
這個 sizes
範例可能會對效能指標產生顯著影響。如果沒有 33vw
的 sizes,從伺服器選擇的圖片寬度會是實際需要的 3 倍。由於檔案大小與寬度的平方成正比,沒有 sizes
時,使用者下載的圖片會比實際需要的大 9 倍。
了解更多關於 srcset
和 sizes
:
quality
最佳化圖片的品質,介於 1
到 100
之間的整數,100
為最佳品質。預設為 75
。
priority
當設為 true 時,圖片將被視為高優先級並進行預載入。對於使用 priority
的圖片,延遲載入會自動停用。
您應該對檢測為最大內容繪製 (LCP) 元素的任何圖片使用 priority
屬性。根據不同視口大小,可能需要為多個圖片設定 priority。
僅當圖片在首屏可見時使用。預設為 false
。
placeholder
圖片載入時使用的佔位符。可能的值為 blur
或 empty
。預設為 empty
。
當設為 blur
時,將使用 blurDataURL
屬性作為佔位符。如果 src
是靜態匯入的物件且匯入的圖片是 .jpg
、.png
、.webp
或 .avif
,則 blurDataURL
會自動填充。
對於動態圖片,您必須提供 blurDataURL
屬性。像 Plaiceholder 這樣的解決方案可以幫助生成 base64
。
當設為 empty
時,圖片載入期間不會有佔位符,只有空白空間。
試試看:
進階屬性
在某些情況下,您可能需要更高級的使用方式。<Image />
元件可選地接受以下進階屬性。
style
允許傳遞 CSS 樣式給底層的圖片元素。
請注意,所有 layout
模式都會對圖片元素應用自己的樣式,這些自動樣式優先於 style
prop。
還要注意,必要的 width
和 height
props 可能會與您的樣式互動。如果您使用樣式修改圖片的 width
,則必須同時設定 height="auto"
樣式,否則圖片會變形。
objectFit
定義當使用 layout="fill"
時,圖片如何適應其父容器。
此值傳遞給 src
圖片的 object-fit CSS 屬性。
objectPosition
定義當使用 layout="fill"
時,圖片在其父元素中的定位方式。
此值傳遞給應用於圖片的 object-position CSS 屬性。
onLoadingComplete
一個回調函式,在圖片完全載入且佔位符被移除後呼叫。
onLoadingComplete
函式接受一個參數,該參數是具有以下屬性的物件:
loading
圖片的載入行為。預設為 lazy
。
當設為 lazy
時,延遲載入圖片直到它到達與視口的計算距離。
當設為 eager
時,立即載入圖片。
blurDataURL
一個資料 URL,在 src
圖片成功載入前用作佔位圖片。僅在與 placeholder="blur"
結合使用時生效。
必須是 base64 編碼的圖片。它會被放大和模糊處理,因此建議使用非常小的圖片(10px 或更小)。包含較大的圖片作為佔位符可能會損害應用程式效能。
試試看:
您也可以生成純色資料 URL 來匹配圖片。
lazyBoundary
一個字串(語法類似於 margin 屬性),用作檢測視口與圖片交集並觸發延遲載入的邊界框。預設為 "200px"
。
如果圖片嵌套在根文件以外的可滾動父元素中,您還需要指定 lazyRoot prop。
lazyRoot
一個指向可滾動父元素的 React Ref。預設為 null
(文件視口)。
Ref 必須指向 DOM 元素或將 Ref 轉發到底層 DOM 元素的 React 元件。
指向 DOM 元素的範例
import Image from 'next/legacy/image'
import React from 'react'
const Example = () => {
const lazyRoot = React.useRef(null)
return (
<div ref={lazyRoot} style={{ overflowX: 'scroll', width: '500px' }}>
<Image lazyRoot={lazyRoot} src="/one.jpg" width="500" height="500" />
<Image lazyRoot={lazyRoot} src="/two.jpg" width="500" height="500" />
</div>
)
}
指向 React 元件的範例
import Image from 'next/legacy/image'
import React from 'react'
const Container = React.forwardRef((props, ref) => {
return (
<div ref={ref} style={{ overflowX: 'scroll', width: '500px' }}>
{props.children}
</div>
)
})
const Example = () => {
const lazyRoot = React.useRef(null)
return (
<Container ref={lazyRoot}>
<Image lazyRoot={lazyRoot} src="/one.jpg" width="500" height="500" />
<Image lazyRoot={lazyRoot} src="/two.jpg" width="500" height="500" />
</Container>
)
}
unoptimized
當設定為 true
時,src
中的原始圖片將直接使用,不會改變品質、大小或格式。預設值為 false
。
這對於無法從優化中受益的圖片非常有用,例如小圖片(小於 1KB)、向量圖片(SVG)或動畫圖片(GIF)。
import Image from 'next/image'
const UnoptimizedImage = (props) => {
return <Image {...props} unoptimized />
}
自 Next.js 12.3.0 起,可以透過更新 next.config.js
並加入以下配置,將此屬性套用至所有圖片:
module.exports = {
images: {
unoptimized: true,
},
}
其他屬性
<Image />
元件的其他屬性將傳遞給底層的 img
元素,但以下屬性除外:
srcSet
。請改用 裝置尺寸 (Device Sizes)。ref
。請改用onLoadingComplete
。decoding
。它始終為"async"
。
配置選項
遠端模式 (Remote Patterns)
為了保護您的應用程式免受惡意使用者攻擊,使用外部圖片時需要進行配置。這確保只有來自您帳戶的外部圖片可以透過 Next.js 圖片優化 API 提供。這些外部圖片可以在 next.config.js
檔案中使用 remotePatterns
屬性進行配置,如下所示:
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'example.com',
port: '',
pathname: '/account123/**',
search: '',
},
],
},
}
須知:上述範例將確保
next/legacy/image
的src
屬性必須以https://example.com/account123/
開頭,且不能有查詢字串。任何其他協定、主機名稱、連接埠或不匹配的路徑將回傳 400 Bad Request。
以下是 next.config.js
檔案中使用 hostname
萬用字元模式的 remotePatterns
屬性範例:
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: '**.example.com',
port: '',
search: '',
},
],
},
}
須知:上述範例將確保
next/legacy/image
的src
屬性必須以https://img1.example.com
或https://me.avatar.example.com
或任何數量的子網域開頭。它不能有連接埠或查詢字串。任何其他協定或不匹配的主機名稱將回傳 400 Bad Request。
萬用字元模式可用於 pathname
和 hostname
,並具有以下語法:
*
匹配單一路徑段或子網域**
匹配任意數量的路徑段(在結尾)或子網域(在開頭)
**
語法不能在模式的中間使用。
須知:當省略
protocol
、port
、pathname
或search
時,隱含使用萬用字元**
。這不建議使用,因為它可能允許惡意行為者優化您無意允許的 URL。
以下是 next.config.js
檔案中使用 search
的 remotePatterns
屬性範例:
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'assets.example.com',
search: '?v=1727111025337',
},
],
},
}
須知:上述範例將確保
next/legacy/image
的src
屬性必須以https://assets.example.com
開頭,且必須具有確切的查詢字串?v=1727111025337
。任何其他協定或查詢字串將回傳 400 Bad Request。
網域 (Domains)
警告:自 Next.js 14 起已棄用,轉而使用嚴格的
remotePatterns
以保護您的應用程式免受惡意使用者攻擊。僅在您擁有該網域提供的所有內容時才使用domains
。
與 remotePatterns
類似,domains
配置可用於提供允許的外部圖片主機名稱列表。
然而,domains
配置不支援萬用字元模式匹配,也無法限制協定、連接埠或路徑名稱。
以下是 next.config.js
檔案中的 domains
屬性範例:
module.exports = {
images: {
domains: ['assets.acme.com'],
},
}
載入器配置 (Loader Configuration)
如果您想使用雲端供應商來優化圖片,而不是使用 Next.js 內建的圖片優化 API,您可以在 next.config.js
檔案中配置 loader
和 path
前綴。這允許您為圖片的 src
使用相對 URL,並自動為您的供應商生成正確的絕對 URL。
module.exports = {
images: {
loader: 'imgix',
path: 'https://example.com/myaccount/',
},
}
內建載入器 (Built-in Loaders)
以下圖片優化雲端供應商已包含:
- 預設:自動適用於
next dev
、next start
或自訂伺服器 - Vercel:部署在 Vercel 時自動適用,無需配置。了解更多
- Imgix:
loader: 'imgix'
- Cloudinary:
loader: 'cloudinary'
- Akamai:
loader: 'akamai'
- 自訂:
loader: 'custom'
透過在next/legacy/image
元件上實作loader
屬性來使用自訂雲端供應商
如果您需要其他供應商,可以使用 next/legacy/image
的 loader
屬性。
使用
output: 'export'
時,圖片無法在構建時優化,僅能按需優化。要將next/legacy/image
與output: 'export'
一起使用,您需要使用非預設的載入器。在討論中了解更多。
進階
以下配置適用於進階使用情境,通常不需要。如果您選擇配置以下屬性,將覆蓋未來更新中 Next.js 預設的任何變更。
裝置尺寸 (Device Sizes)
如果您知道使用者的預期裝置寬度,可以在 next.config.js
中使用 deviceSizes
屬性指定裝置寬度斷點列表。當 next/legacy/image
元件使用 layout="responsive"
或 layout="fill"
時,這些寬度用於確保為使用者的裝置提供正確的圖片。
如果未提供配置,則使用以下預設值。
module.exports = {
images: {
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
},
}
圖片尺寸 (Image Sizes)
您可以在 next.config.js
檔案中使用 images.imageSizes
屬性指定圖片寬度列表。這些寬度與 裝置尺寸 (device sizes) 陣列連接,形成用於生成圖片 srcset 的完整尺寸陣列。
之所以有兩個獨立的列表,是因為 imageSizes
僅用於提供 sizes
屬性的圖片,這表示圖片的寬度小於螢幕的完整寬度。因此,imageSizes
中的尺寸都應小於 deviceSizes
中的最小尺寸。
如果未提供配置,則使用以下預設值。
module.exports = {
images: {
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
},
}
可接受的格式 (Acceptable Formats)
預設的 圖片優化 API 會透過請求的 Accept
標頭自動檢測瀏覽器支援的圖片格式,以確定最佳輸出格式。
如果 Accept
標頭匹配多個配置的格式,則使用陣列中的第一個匹配項。因此,陣列順序很重要。如果沒有匹配項(或來源圖片是 動畫圖片),圖片優化 API 將回退到原始圖片的格式。
如果未提供配置,則使用以下預設值。
module.exports = {
images: {
formats: ['image/webp'],
},
}
您可以啟用 AVIF 支援,如果瀏覽器 不支援 AVIF,則會回退到 src
圖片的原始格式:
module.exports = {
images: {
formats: ['image/avif'],
},
}
須知:
- 我們仍然建議在大多數使用情境中使用 WebP。
- AVIF 通常需要多 50% 的時間來編碼,但與 WebP 相比,壓縮率高出 20%。這意味著首次請求圖片時通常會較慢,但後續的快取請求會更快。
- 如果您在 Next.js 前使用 Proxy/CDN 自託管,必須配置 Proxy 轉發
Accept
標頭。
快取行為 (Caching Behavior)
以下描述預設 載入器 (loader) 的快取演算法。對於所有其他載入器,請參考您的雲端供應商文件。
圖片在請求時動態優化,並儲存在 <distDir>/cache/images
目錄中。優化後的圖片檔案將用於後續請求,直到過期為止。當請求匹配到已快取但已過期的檔案時,會立即提供過期的圖片(稱為 stale)。然後在背景中重新優化圖片(也稱為重新驗證 (revalidation)),並使用新的過期日期儲存到快取中。
可以透過讀取 x-nextjs-cache
(部署在 Vercel 時為 x-vercel-cache
)回應標頭的值來確定圖片的快取狀態。可能的值如下:
MISS
- 路徑不在快取中(最多發生一次,在首次訪問時)STALE
- 路徑在快取中,但已超過重新驗證時間,因此將在背景中更新HIT
- 路徑在快取中,且未超過重新驗證時間
過期時間(或稱最大壽命 (Max Age))由 minimumCacheTTL
配置或上游圖片的 Cache-Control
標頭中的較大者定義。具體來說,使用 Cache-Control
標頭的 max-age
值。如果同時找到 s-maxage
和 max-age
,則優先使用 s-maxage
。max-age
也會傳遞給任何下游客戶端,包括 CDN 和瀏覽器。
- 您可以配置
minimumCacheTTL
以在上游圖片不包含Cache-Control
標頭或值非常低時增加快取時間。 - 您可以配置
deviceSizes
和imageSizes
以減少可能生成的圖片總數。 - 您可以配置 格式 (formats) 以停用多種格式,僅使用單一圖片格式。
最小快取 TTL (Minimum Cache TTL)
您可以為快取的優化圖片配置存留時間 (TTL)(以秒為單位)。在許多情況下,最好使用 靜態圖片導入 (Static Image Import),它會自動對檔案內容進行雜湊處理,並使用 Cache-Control
標頭 immutable
永久快取圖片。
如果未提供配置,則使用以下預設值。
module.exports = {
images: {
minimumCacheTTL: 60, // 1 分鐘
},
}
您可以增加 TTL 以減少重新驗證次數,並可能降低成本:
module.exports = {
images: {
minimumCacheTTL: 2678400, // 31 天
},
}
優化圖片的過期時間(或稱最大壽命)由 minimumCacheTTL
或上游圖片的 Cache-Control
標頭中的較大者定義。
如果需要按圖片更改快取行為,可以配置 headers
在上游圖片(例如 /some-asset.jpg
,而不是 /_next/image
本身)上設定 Cache-Control
標頭。
目前沒有機制可以手動使快取失效,因此最好保持 minimumCacheTTL
較低。否則,您可能需要手動更改 src
屬性或刪除 <distDir>/cache/images
。
停用靜態導入 (Disable Static Imports)
預設行為允許您導入靜態檔案,例如 import icon from './icon.png'
,然後將其傳遞給 src
屬性。
在某些情況下,如果與其他預期導入行為不同的插件衝突,您可能希望停用此功能。
您可以在 next.config.js
中停用靜態圖片導入:
module.exports = {
images: {
disableStaticImages: true,
},
}
危險允許 SVG (Dangerously Allow SVG)
預設的 載入器 (loader) 不會優化 SVG 圖片,原因有幾個。首先,SVG 是一種向量格式,意味著它可以無損縮放。其次,SVG 具有許多與 HTML/CSS 相同的功能,如果沒有適當的 內容安全政策 (Content Security Policy, CSP) 標頭,可能導致漏洞。
因此,我們建議在 src
屬性已知為 SVG 時使用 unoptimized
屬性。當 src
以 ".svg"
結尾時,這會自動發生。
但是,如果您需要使用預設的圖片優化 API 提供 SVG 圖片,可以在 next.config.js
中設定 dangerouslyAllowSVG
:
module.exports = {
images: {
dangerouslyAllowSVG: true,
contentDispositionType: 'attachment',
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
},
}
此外,強烈建議同時設定 contentDispositionType
以強制瀏覽器下載圖片,以及 contentSecurityPolicy
以防止嵌入在圖片中的腳本執行。
contentDispositionType
預設的 載入器 (loader) 將 Content-Disposition
標頭設定為 attachment
以增加保護,因為 API 可以提供任意的遠端圖片。
預設值為 attachment
,這會強制瀏覽器在直接訪問時下載圖片。這在 dangerouslyAllowSVG
為 true
時尤其重要。
您可以選擇配置 inline
以允許瀏覽器在直接訪問時渲染圖片,而不是下載它。
module.exports = {
images: {
contentDispositionType: 'inline',
},
}
動畫圖片 (Animated Images)
預設的 載入器 (loader) 會自動繞過動畫圖片的優化,並直接提供原始圖片。
對動畫檔案的自動檢測是盡力而為的,支援 GIF、APNG 和 WebP。如果您想明確繞過特定動畫圖片的優化,請使用 unoptimized 屬性。
版本歷史
版本 | 變更 |
---|---|
v13.0.0 | next/image 更名為 next/legacy/image |