Image(旧版)
从 Next.js 13 开始,next/image
组件经过重构以提升性能和开发者体验。为了提供向后兼容的升级方案,旧版 next/image
已重命名为 next/legacy/image
。
查看新版 next/image
API 参考文档
新旧对比
与 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
必须为以下类型之一:
使用默认 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 属性会覆盖 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
尺寸,从服务器选择的图片宽度会是实际需要的 3 倍。由于文件大小与宽度的平方成正比,没有 sizes
时用户会下载比实际需要大 9 倍的图片。
了解更多关于 srcset
和 sizes
:
quality
优化图片的质量,整数范围 1
到 100
,100
为最佳质量。默认为 75
。
priority
当为 true
时,图片将被视为高优先级并启用 预加载。使用 priority
的图片会自动禁用懒加载。
应在检测为 最大内容绘制 (LCP) 元素的图片上使用 priority
属性。对于不同视口尺寸,可能有多个优先级图片是合适的。
仅当图片在首屏可见时使用。默认为 false
。
placeholder
图片加载时使用的占位符。可选值为 blur
或 empty
。默认为 empty
。
当为 blur
时,将使用 blurDataURL
属性作为占位符。如果 src
是 静态导入 的对象且导入的图片为 .jpg
、.png
、.webp
或 .avif
格式,则 blurDataURL
会自动填充。
对于动态图片,必须提供 blurDataURL
属性。可以使用 Plaiceholder 等工具生成 base64
。
当为 empty
时,图片加载期间不会有占位符,只有空白空间。
尝试以下示例:
高级属性
在某些情况下,可能需要更高级的用法。<Image />
组件可选地接受以下高级属性。
style
允许 传递 CSS 样式 到底层图片元素。
注意,所有 layout
模式都会自动应用自己的样式到图片元素,这些自动样式优先于 style
属性。
还需注意,必填的 width
和 height
属性可能与样式交互。如果使用样式修改图片的 width
,则必须同时设置 height="auto"
样式,否则图片会变形。
objectFit
定义当使用 layout="fill"
时图片如何适应其父容器。
此值传递给 src
图片的 object-fit CSS 属性。
objectPosition
定义当使用 layout="fill"
时图片在其父元素中的定位方式。
此值传递给应用于图片的 object-position CSS 属性。
onLoadingComplete
一个回调函数,在图片完全加载且 占位符 移除后调用。
onLoadingComplete
函数接收一个参数,包含以下属性的对象:
loading
图片的加载行为。默认为 lazy
。
当为 lazy
时,延迟加载图片直到其到达与视口的计算距离。
当为 eager
时,立即加载图片。
blurDataURL
一个 Data URL,在 src
图片成功加载前用作占位图片。仅在与 placeholder="blur"
结合使用时生效。
必须是 base64 编码的图片。会被放大和模糊处理,因此建议使用非常小的图片(10px 或更小)。包含较大的占位图可能会影响应用性能。
尝试以下示例:
也可以 生成纯色 Data URL 以匹配图片。
lazyBoundary
一个字符串(语法类似于 margin 属性),用作检测视口与图片交集的边界框,触发懒 加载。默认为 "200px"
。
如果图片嵌套在根文档以外的可滚动父元素中,还需要指定 lazyRoot 属性。
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
文件中 remotePatterns
属性使用 hostname
通配符模式的示例:
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
文件中 remotePatterns
属性使用 search
的示例:
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
前缀。这样可以使用相对 URL 作为图像的 src
,并自动为您的提供商生成正确的绝对 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
属性指定图像宽度列表。这些宽度与 设备尺寸 数组拼接,形成用于生成图像 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 编码通常比 WebP 多花 50% 的时间,但压缩率比 WebP 高 20%。这意味着首次请求图像时通常会较慢,但后续缓存的请求会更快。
- 如果您在 Next.js 前使用代理/CDN 自托管,必须配置代理转发
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
以减少可能生成的图像总数。 - 可以配置 格式 以禁用多种格式,仅使用单一图像格式。
最小缓存 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)
默认的 加载器 出于几个原因不优化 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',
},
}
动态图像 (Animated Images)
默认的 加载器 会自动绕过动态图像的优化,直接提供原图。
动态文件的自动检测是尽力而为的,支持 GIF、APNG 和 WebP。如果希望显式绕过特定动态图像的优化,请使用 unoptimized 属性。
版本历史
版本 | 变更 |
---|---|
v13.0.0 | next/image 更名为 next/legacy/image |