Image (Legacy)
從 Next.js 13 開始,`next/image` 元件經過重寫,以提高效能和開發體驗。為了提供向後相容的升級方案,舊的 `next/image` 被重新命名為 `next/legacy/image`。
警告:`next/legacy/image` 已棄用,並將在未來的 Next.js 版本中移除。請改用 `next/image`。
比較
與 `next/legacy/image` 相比,新的 `next/image` 元件有以下變化:
- 移除 `<img>` 周圍的 `<span>` 包裝器,轉而使用 原生計算寬高比
- 新增對標準 `style` 屬性的支援
- 移除 `layout` 屬性,轉而使用 `style` 或 `className`
- 移除 `objectFit` 屬性,轉而使用 `style` 或 `className`
- 移除 `objectPosition` 屬性,轉而使用 `style` 或 `className`
- 移除 `IntersectionObserver` 實現,轉而使用 原生延遲載入
- 移除 `lazyBoundary` 屬性,因為沒有原生等效項
- 移除 `lazyRoot` 屬性,因為沒有原生等效項
- 移除 `loader` 配置,轉而使用 `loader` 屬性
- 將 `alt` 屬性從可選改為必填
- 將 `onLoadingComplete` 回撥更改為接收 `<img>` 元素的引用
必需屬性
Image 元件需要以下屬性。
src
必須是以下之一:
使用預設 載入器 時,還應考慮源圖片的以下情況:
- 當 src 為外部 URL 時,您還必須配置 remotePatterns
- 當 src 為動畫或未知格式(JPEG、PNG、WebP、AVIF、GIF、TIFF)時,圖片將按原樣提供
- 當 src 為 SVG 格式時,除非啟用 `unoptimized` 或 `dangerouslyAllowSVG`,否則將被阻止
寬度
`width` 屬性可以表示畫素的*渲染*寬度或*原始*寬度,具體取決於 `layout` 和 `sizes` 屬性。
使用 `layout="intrinsic"` 或 `layout="fixed"` 時,`width` 屬性表示以畫素為單位的*渲染*寬度,因此會影響影像的顯示大小。
當使用 `layout="responsive"`、`layout="fill"` 時,`width` 屬性表示以畫素為單位的*原始*寬度,因此它只會影響寬高比。
除了靜態匯入的圖片或 `layout="fill"` 的圖片外,`width` 屬性是必需的。
高度
`height` 屬性可以表示畫素的*渲染*高度或*原始*高度,具體取決於 `layout` 和 `sizes` 屬性。
使用 `layout="intrinsic"` 或 `layout="fixed"` 時,`height` 屬性表示以畫素為單位的*渲染*高度,因此會影響影像的顯示大小。
當使用 `layout="responsive"`、`layout="fill"` 時,`height` 屬性表示以畫素為單位的*原始*高度,因此它只會影響寬高比。
除了靜態匯入的圖片或 `layout="fill"` 的圖片外,`height` 屬性是必需的。
可選屬性
Image 元件除了必需的屬性外,還接受許多附加屬性。本節介紹 Image 元件最常用的屬性。有關不常用屬性的詳細資訊,請參見高階屬性部分。
佈局
當視口尺寸改變時,影像的佈局行為。
佈局 | 行為 | srcSet | 尺寸 | 有包裝器和尺寸器 |
|---|---|---|---|---|
| 固有(預設) | 縮小以適應容器寬度,最大不超過影像尺寸 | 1x,2x(基於影像尺寸) | 不適用 | 是 |
固定 | 精確調整為 `width` 和 `height` | 1x,2x(基於影像尺寸) | 不適用 | 是 |
響應式 | 按比例縮放以適應容器寬度 | 640w、750w、... 2048w、3840w(基於影像尺寸和裝置尺寸) | 100vw | 是 |
填充 | 在X和Y軸上同時增長以填充容器 | 640w、750w、... 2048w、3840w(基於影像尺寸和裝置尺寸) | 100vw | 是 |
- 演示 `intrinsic` 佈局(預設)
- 當 `intrinsic` 時,圖片會針對較小的視口縮小尺寸,但對於較大的視口則保持原始尺寸。
- 演示 `fixed` 佈局
- 當 `fixed` 時,影像尺寸不會隨視口變化而改變(無響應性),類似於原生 `img` 元素。
- 演示 `responsive` 佈局
- 當 `responsive` 時,影像會針對較小的視口縮小尺寸,並針對較大的視口放大尺寸。
- 請確保父元素在其樣式表中使用了 `display: block`。
- 演示 `fill` 佈局
- 當 `fill` 時,影像的寬度和高度都將拉伸至父元素的尺寸,前提是父元素是相對定位的。
- 這通常與 `objectFit` 屬性搭配使用。
- 確保父元素在其樣式表中具有 `position: relative`。
- 演示背景圖片
載入器
一個用於解析 URL 的自定義函式。在 Image 元件上將載入器設定為屬性會覆蓋 `next.config.js` 中`images` 部分定義的預設載入器。
`loader` 是一個函式,給定以下引數,返回影像的 URL 字串:
這是一個使用自定義載入器的示例:
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}
/>
)
}尺寸
一個字串,提供關於影像在不同斷點處的寬度資訊。對於使用 `layout="responsive"` 或 `layout="fill"` 的影像,`sizes` 的值將極大地影響效能。對於使用 `layout="intrinsic"` 或 `layout="fixed"` 的影像,它將被忽略。
`sizes` 屬性在影像效能方面具有兩個重要目的:
首先,`sizes` 的值被瀏覽器用於確定要從 `next/legacy/image` 自動生成的源集中下載哪種尺寸的影像。當瀏覽器選擇時,它還不知道頁面上影像的大小,因此它選擇一個與視口大小相同或更大的影像。`sizes` 屬性允許您告訴瀏覽器影像實際上會小於全屏。如果您未指定 `sizes` 值,則使用預設值 `100vw`(全屏寬度)。
其次,解析並使用 `sizes` 值來修剪自動建立的源集中的值。如果 `sizes` 屬性包含 `50vw` 等大小,這些大小表示視口寬度的百分比,則會修剪源集,使其不包含任何太小而無需的值。
例如,如果您知道您的樣式會導致影像在移動裝置上全寬顯示,在平板電腦上採用兩列布局,在桌面顯示器上採用三列布局,您應該包含一個 `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` 的尺寸,從伺服器選擇的影像將比所需的寬 3 倍。由於檔案大小與寬度的平方成正比,因此如果沒有 `sizes`,使用者將下載比必要大 9 倍的影像。
瞭解有關 `srcset` 和 `sizes` 的更多資訊
質量
最佳化影像的質量,一個介於 `1` 和 `100` 之間的整數,其中 `100` 是最佳質量。預設為 `75`。
優先順序
當為 true 時,影像將被視為高優先順序並進行預載入。對於使用 `priority` 的影像,延遲載入會自動停用。
您應該對任何被檢測為 最大內容繪製 (LCP) 元素的影像使用 `priority` 屬性。可能適合使用多個優先順序影像,因為不同的影像可能是不同視口尺寸的 LCP 元素。
僅當圖片可見且在首屏上方時才應使用。預設為 `false`。
佔位符
在影像載入期間使用的佔位符。可能的值為 `blur` 或 `empty`。預設為 `empty`。
當設定為 `blur` 時,`blurDataURL` 屬性將用作佔位符。如果 `src` 是來自靜態匯入的物件,並且匯入的影像是 `.jpg`、`.png`、`.webp` 或 `.avif` 格式,則 `blurDataURL` 將自動填充。
對於動態圖片,您必須提供 `blurDataURL` 屬性。像 Plaiceholder 等解決方案可以幫助生成 `base64`。
當 `empty` 時,影像載入時不會有佔位符,只有空白區域。
嘗試一下
高階屬性
在某些情況下,您可能需要更高階的用法。`<Image />` 元件可選接受以下高階屬性。
樣式
允許將 CSS 樣式 傳遞給底層影像元素。
請注意,所有 `layout` 模式都會對影像元素應用自己的樣式,並且這些自動樣式優先於 `style` 屬性。
另請記住,必需的 `width` 和 `height` 屬性可以與您的樣式相互作用。如果您使用樣式修改影像的 `width`,則還必須設定 `height="auto"` 樣式,否則您的影像將變形。
objectFit
定義當使用 `layout="fill"` 時,影像如何適應其父容器。
此值被傳遞給 `src` 影像的 object-fit CSS 屬性。
objectPosition
在使用 `layout="fill"` 時,定義影像在其父元素中的位置。
此值被傳遞給應用於影像的 object-position CSS 屬性。
onLoadingComplete
影像完全載入且佔位符已移除後呼叫的回撥函式。
`onLoadingComplete` 函式接受一個引數,該引數是一個具有以下屬性的物件:
載入
影像的載入行為。預設為 `lazy`。
當 `lazy` 時,延遲載入影像直到其到達距離視口的計算距離。
當 `eager` 時,立即載入影像。
blurDataURL
在 `src` 影像成功載入之前用作佔位符影像的 資料 URL。僅當與 `placeholder="blur"` 結合使用時才生效。
必須是 base64 編碼的影像。它將被放大和模糊,因此建議使用非常小的影像(10 畫素或更小)。包含較大的影像作為佔位符可能會損害您的應用程式效能。
嘗試一下
您還可以生成純色資料 URL 以匹配影像。
lazyBoundary
一個字串(語法類似於 `margin` 屬性),充當用於檢測視口與影像交集並觸發延遲載入的邊界框。預設為 `"200px"`。
如果影像巢狀在除根文件之外的可滾動父元素中,您還需要分配 lazyRoot 屬性。
lazyRoot
指向可滾動父元素的 React 引用。預設為 `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>
)
}未最佳化
當為 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`。請改用裝置尺寸。
- `ref`。請改用`onLoadingComplete`。
- `decoding`。它始終是 `"async"`。
配置選項
遠端模式
為了保護您的應用程式免受惡意使用者的侵害,使用外部影像需要進行配置。這確保只有您賬戶中的外部影像才能透過 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。
域名
警告:自 Next.js 14 起已棄用,轉而採用嚴格的 `remotePatterns`,以保護您的應用程式免受惡意使用者侵害。僅當您擁有該域名提供的所有內容時才使用 `domains`。
類似於 `remotePatterns`,`domains` 配置可用於提供外部影像的允許主機名列表。
但是,`domains` 配置不支援萬用字元模式匹配,也無法限制協議、埠或路徑名。
以下是 next.config.js 檔案中 domains 屬性的示例
module.exports = {
images: {
domains: ['assets.acme.com'],
},
}載入器配置
如果您想使用雲提供商而不是 Next.js 內建影像最佳化 API 來最佳化影像,您可以在 `next.config.js` 檔案中配置 `loader` 和 `path` 字首。這允許您對影像 `src` 使用相對 URL,並自動為您的提供商生成正確的絕對 URL。
module.exports = {
images: {
loader: 'imgix',
path: 'https://example.com/myaccount/',
},
}自定義內建圖片路徑
如果您想更改或為內建 Next.js 影像最佳化新增字首,可以使用 `path` 屬性進行操作。`path` 的預設值為 `/_next/image`。
module.exports = {
images: {
path: '/my-prefix/_next/image',
},
}內建載入器
以下影像最佳化雲提供商已包含:
- 預設:與 `next dev`、`next start` 或自定義伺服器自動工作
- Vercel:部署到 Vercel 時自動工作,無需配置。瞭解更多
- Imgix: `loader: 'imgix'`
- Cloudinary: `loader: 'cloudinary'`
- Akamai: `loader: 'akamai'`
- 自定義:`loader: 'custom'`,透過在 `next/legacy/image` 元件上實現 `loader` 屬性來使用自定義雲提供商。
如果您需要其他提供商,可以將 `loader` 屬性與 `next/legacy/image` 一起使用。
圖片無法在構建時使用 `output: 'export'` 進行最佳化,只能按需最佳化。要將 `next/legacy/image` 與 `output: 'export'` 一起使用,您需要使用不同於預設的載入器。在討論中瞭解更多資訊。
高階
以下配置用於高階用例,通常不需要。如果您選擇配置以下屬性,您將覆蓋未來更新中對 Next.js 預設值的任何更改。
裝置尺寸
如果您知道使用者的預期裝置寬度,您可以在 `next.config.js` 中使用 `deviceSizes` 屬性指定裝置寬度斷點列表。當 `next/legacy/image` 元件使用 `layout="responsive"` 或 `layout="fill"` 時,這些寬度用於確保為使用者的裝置提供正確的影像。
如果未提供配置,則使用以下預設值。
module.exports = {
images: {
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
},
}影像尺寸
您可以在 `next.config.js` 檔案中使用 `images.imageSizes` 屬性指定影像寬度列表。這些寬度與裝置尺寸陣列連線,形成用於生成影像 srcset 的完整尺寸陣列。
之所以有這兩個獨立的列表,是因為 `imageSizes` 僅用於提供 `sizes` 屬性的影像,這表明影像的寬度小於螢幕的全部寬度。因此,`imageSizes` 中的所有尺寸都應小於 `deviceSizes` 中的最小尺寸。
如果未提供配置,則使用以下預設值。
module.exports = {
images: {
imageSizes: [32, 48, 64, 96, 128, 256, 384],
},
}可接受的格式
預設的影像最佳化 API 將透過請求的 `Accept` 頭自動檢測瀏覽器支援的影像格式,以確定最佳輸出格式。
如果 `Accept` 標頭匹配多個配置的格式,則使用陣列中的第一個匹配項。因此,陣列順序很重要。如果沒有匹配項(或源影像是動畫),影像最佳化 API 將回退到原始影像的格式。
如果未提供配置,則使用以下預設值。
module.exports = {
images: {
formats: ['image/webp'],
},
}您可以啟用 AVIF 支援,如果瀏覽器不支援 AVIF,它將回退到 src 影像的原始格式
module.exports = {
images: {
formats: ['image/avif'],
},
}須知:
- 我們仍然建議在大多數用例中使用 WebP。
- AVIF 通常需要多 50% 的編碼時間,但與 WebP 相比,它壓縮後文件大小小 20%。這意味著影像首次請求時通常會更慢,然後後續快取的請求會更快。
- 如果您使用 Proxy/CDN 在 Next.js 前面進行自託管,則必須配置 Proxy 以轉發
Accept頭部。
快取行為
以下描述了預設載入器的快取演算法。對於所有其他載入器,請參閱您的雲提供商文件。
影像在請求時動態最佳化並存儲在 `<distDir>/cache/images` 目錄中。最佳化後的影像檔案將用於後續請求,直到達到過期時間。當請求匹配到已快取但已過期的檔案時,過期的影像會立即提供陳舊版本。然後影像會在後臺再次最佳化(也稱為重新驗證),並以新的過期日期儲存到快取中。
影像的快取狀態可以透過讀取 `x-nextjs-cache`(部署在 Vercel 上時為 `x-vercel-cache`)響應標頭的值來確定。可能的值如下:
- `MISS` - 路徑不在快取中(最多發生一次,首次訪問時)
- STALE - 路徑在快取中,但已超過重新驗證時間,因此將在後臺更新。
- HIT - 路徑在快取中且未超過重新驗證時間。
過期時間(或更確切地說是最大存活期)由 `minimumCacheTTL` 配置或上游影像 `Cache-Control` 標頭定義,以兩者中較大的為準。具體來說,使用 `Cache-Control` 標頭的 `max-age` 值。如果同時找到 `s-maxage` 和 `max-age`,則首選 `s-maxage`。`max-age` 也傳遞給包括 CDN 和瀏覽器在內的任何下游客戶端。
- 當上遊圖片不包含 `Cache-Control` 標頭或其值很低時,您可以配置 `minimumCacheTTL` 來增加快取持續時間。
- 您可以配置 `deviceSizes` 和 `imageSizes` 以減少可能生成的影像總數。
- 您可以配置 formats 以停用多種格式,轉而使用單一影像格式。
最小快取 TTL
您可以配置快取最佳化影像的生存時間(TTL),以秒為單位。在許多情況下,最好使用 靜態影像匯入,它會自動對檔案內容進行雜湊處理,並使用 `immutable` 的 `Cache-Control` 標頭永久快取影像。
如果未提供配置,則使用以下預設值。
module.exports = {
images: {
minimumCacheTTL: 14400, // 4 hours
},
}您可以增加 TTL 以減少重新驗證次數並可能降低成本
module.exports = {
images: {
minimumCacheTTL: 2678400, // 31 days
},
}最佳化影像的過期時間(或者更確切地說是最大壽命)由 minimumCacheTTL 或上游影像 Cache-Control 標頭(以較大者為準)定義。
如果您需要更改每個影像的快取行為,您可以配置 `headers` 以在上游影像(例如 `/some-asset.jpg`,而不是 `/_next/image` 本身)上設定 `Cache-Control` 標頭。
目前還沒有機制來使快取失效,因此最好將 `minimumCacheTTL` 保持在較低水平。否則,您可能需要手動更改 `src` 屬性或刪除 `<distDir>/cache/images`。
停用靜態匯入
預設行為允許您匯入靜態檔案,例如 `import icon from './icon.png'`,然後將其傳遞給 `src` 屬性。
在某些情況下,如果此功能與其他期望匯入行為不同的外掛衝突,您可能希望停用此功能。
您可以在 next.config.js 中停用靜態影像匯入
module.exports = {
images: {
disableStaticImages: true,
},
}危險地允許 SVG
預設的載入器不最佳化 SVG 影像有幾個原因。首先,SVG 是一種向量格式,這意味著它可以無損地調整大小。其次,SVG 具有與 HTML/CSS 許多相同的功能,如果沒有適當的內容安全策略 (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
預設的載入器將 `Content-Disposition` 標頭設定為 `attachment`,以增加保護,因為 API 可以提供任意遠端影像。
預設值為 `attachment`,它強制瀏覽器在直接訪問時下載影像。當 `dangerouslyAllowSVG` 為 true 時,這一點尤為重要。
您可以選擇配置 inline,以允許瀏覽器在直接訪問時呈現影像,而無需下載。
module.exports = {
images: {
contentDispositionType: 'inline',
},
}動畫影像
預設的載入器將自動繞過動畫影像的影像最佳化,並按原樣提供影像。
動畫檔案的自動檢測是盡力而為的,支援 GIF、APNG 和 WebP。如果您想明確繞過給定動畫影像的影像最佳化,請使用 unoptimized 屬性。
版本歷史
| 版本 | 更改 |
|---|---|
v16.0.0 | `next/legacy/image` 已棄用,並將在未來的 Next.js 版本中移除。請改用 `next/image`。 |
v13.0.0 | `next/image` 重新命名為 `next/legacy/image` |
這有幫助嗎?