Image (旧版)
示例
从 Next.js 13 开始,next/image
组件被重写,以提高性能和开发者体验。为了提供向后兼容的升级解决方案,旧的 next/image
被重命名为 next/legacy/image
。
查看新的 next/image
API 参考
比较
与 next/legacy/image
相比,新的 next/image
组件有以下更改
- 移除
<span>
包装器,围绕<img>
,转而使用 原生计算的宽高比 - 添加对规范
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
一个字符串,提供有关图像在不同断点处的宽度的信息。对于使用 layout="responsive"
或 layout="fill"
的图像,sizes
的值将极大地影响性能。对于使用 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
属性。可能有多个优先级图像是合适的,因为不同的图像可能是不同视口尺寸的 LCP 元素。
仅当图像在首屏可见时才应使用。默认为 false
。
placeholder
图像加载时要使用的占位符。可能的值为 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
函数接受一个参数,该参数是一个具有以下属性的对象:
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
。请改用设备尺寸。ref
。请改用onLoadingComplete
。decoding
。它始终为"async"
。
配置选项
远程模式
为了保护您的应用程序免受恶意用户的攻击,需要进行配置才能使用外部图像。这确保只有来自您帐户的外部图像才能从 Next.js Image Optimization 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 内置的 Image Optimization API,您可以在 next.config.js
文件中配置 loader
和 path
前缀。这允许您为 Image src
使用相对 URL,并自动为您的提供商生成正确的绝对 URL。
module.exports = {
images: {
loader: 'imgix',
path: 'https://example.com/myaccount/',
},
}
内置加载器
包含以下 Image Optimization 云提供商:
- 默认:与
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 默认值的任何更改。
设备尺寸
如果您知道用户的预期设备宽度,则可以使用 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
属性指定图像宽度列表。这些宽度与设备尺寸数组连接,形成用于生成图像 srcsets 的完整尺寸数组。
存在两个单独列表的原因是 imageSizes 仅用于提供 sizes
属性的图像,这表明图像小于屏幕的完整宽度。因此,imageSizes 中的尺寸都应小于 deviceSizes 中最小的尺寸。
如果未提供配置,则使用以下默认值。
module.exports = {
images: {
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
},
}
可接受的格式
默认的 Image Optimization API 将自动检测浏览器支持的图像格式,通过请求的 Accept
标头来确定最佳输出格式。
如果 Accept
标头匹配多个配置的格式,则使用数组中的第一个匹配项。因此,数组顺序很重要。如果没有匹配项(或者源图像是动画),Image Optimization 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
标头。
缓存行为
以下描述了默认 loader 的缓存算法。对于所有其他加载器,请参阅您的云提供商的文档。
图像在请求时动态优化,并存储在 <distDir>/cache/images
目录中。优化的图像文件将为后续请求提供服务,直到过期时间到达。当发出的请求与缓存但已过期的文件匹配时,将立即提供过期的旧图像。然后,图像在后台再次优化(也称为重新验证),并使用新的过期日期保存到缓存中。
可以通过读取 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 和浏览器。
- 当上游图像不包含
Cache-Control
标头或该值非常低时,您可以配置minimumCacheTTL
以增加缓存持续时间。 - 您可以配置
deviceSizes
和imageSizes
以减少可能生成的图像总数。 - 您可以配置 formats 以禁用多种格式,而只支持单一图像格式。
最小缓存 TTL
您可以配置缓存优化图像的生存时间 (TTL),以秒为单位。在许多情况下,最好使用静态图像导入,这将自动哈希文件内容,并使用 immutable
的 Cache-Control
标头永久缓存图像。
module.exports = {
images: {
minimumCacheTTL: 60,
},
}
优化图像的过期时间(或者更确切地说是 Max Age)由 minimumCacheTTL
或上游图像 Cache-Control
标头定义,以较大者为准。
如果您需要更改每个图像的缓存行为,可以配置 headers
以在上游图像上设置 Cache-Control
标头(例如 /some-asset.jpg
,而不是 /_next/image
本身)。
目前没有使缓存失效的机制,因此最好将 minimumCacheTTL
保持较低的值。否则,您可能需要手动更改 src
属性或删除 <distDir>/cache/images
。
禁用静态导入
默认行为允许您导入静态文件,例如 import icon from './icon.png'
,然后将其传递给 src
属性。
在某些情况下,如果您希望禁用此功能,因为它与其他期望导入行为不同的插件冲突。
您可以在 next.config.js
中禁用静态图像导入
module.exports = {
images: {
disableStaticImages: true,
},
}
危险地允许 SVG
默认的 loader 不会优化 SVG 图像,原因有几个。首先,SVG 是一种矢量格式,这意味着它可以无损地调整大小。其次,SVG 具有许多与 HTML/CSS 相同的功能,如果没有正确的 内容安全策略 (CSP) 标头,可能会导致漏洞。
因此,当 src
属性已知为 SVG 时,我们建议使用 unoptimized
属性。当 src
以 ".svg"
结尾时,会自动发生这种情况。
但是,如果您需要使用默认的 Image Optimization 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',
},
}
动画图像
默认的 加载器 将自动绕过动画图像的图像优化,并按原样提供图像。
自动检测动画文件是尽力而为,并支持 GIF、APNG 和 WebP。如果您想为给定的动画图像显式绕过图像优化,请使用 unoptimized 属性。
版本历史
版本 | 变更 |
---|---|
v13.0.0 | next/image 重命名为 next/legacy/image |
这有帮助吗?