<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
属性可以表示以像素为单位的渲染宽度或原始宽度,具体取决于 layout
和 sizes
属性。
当使用 layout="intrinsic"
或 layout="fixed"
时,width
属性表示以像素为单位的渲染宽度,因此它会影响图像显示的大小。
当使用 layout="responsive"
、layout="fill"
时,width
属性表示以像素为单位的原始宽度,因此它只会影响纵横比。
width
属性是必需的,除了 静态导入的图像 或那些具有 layout="fill"
的图像。
高度
height
属性可以表示以像素为单位的渲染高度或原始高度,具体取决于 layout
和 sizes
属性。
当使用 layout="intrinsic"
或 layout="fixed"
时,height
属性表示以像素为单位的渲染高度,因此它会影响图像显示的大小。
当使用 layout="responsive"
、layout="fill"
时,height
属性表示以像素为单位的原始高度,因此它只会影响纵横比。
height
属性是必需的,除了 静态导入的图像 或那些具有 layout="fill"
的图像。
可选属性
<Image />
组件除了必需的属性之外,还接受许多其他属性。本节介绍 Image 组件最常用的属性。在 高级属性 部分中查找有关不太常用属性的详细信息。
布局
视口大小变化时图像的布局行为。
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
。
- 当
- 演示背景图像
加载器
用于解析 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}
/>
)
}
尺寸
一个字符串,提供有关图像在不同断点处宽度的信息。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
的更多信息。
质量
优化图像的质量,一个介于 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 />
组件可以选择接受以下高级属性。
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
在src
图像成功加载之前用作占位符图像的数据 URL。仅当与placeholder="blur"
结合使用时才有效。
必须是 base64 编码的图像。它将被放大和模糊,因此建议使用非常小的图像(10px 或更小)。包含较大的图像作为占位符可能会损害应用程序性能。
试一试
您还可以生成与图像匹配的纯色数据 URL。
lazyBoundary
一个字符串(与边距属性的语法类似),用作边界框,用于检测视口与图像的交集并触发延迟加载。默认为"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
如果为真,则源图像将按原样提供服务,而不是更改质量、大小或格式。默认为 false
。
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 错误请求。
以下是 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 错误请求。
通配符模式可用于 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 错误请求。
域
警告:自 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
前缀。这允许您对 Image src
使用相对 URL,并自动为您的提供商生成正确的绝对 URL。
module.exports = {
images: {
loader: 'imgix',
path: 'https://example.com/myaccount/',
},
}
内置加载程序
包含以下图像优化云提供商
- 默认:与
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` 属性指定图像宽度的列表。这些宽度与 设备尺寸 的数组连接起来,形成用于生成图像 srcset 的完整尺寸数组。
存在两个单独的列表的原因是,`imageSizes` 仅用于提供 sizes
属性的图像,这表示图像小于屏幕的完整宽度。**因此,`imageSizes` 中的尺寸应都小于 `deviceSizes` 中的最小尺寸。**
如果未提供任何配置,则使用以下默认值。
module.exports = {
images: {
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
},
}
可接受的格式
默认的 图像优化 API 将通过请求的 `Accept` 标头自动检测浏览器支持的图像格式,以确定最佳输出格式。
如果 `Accept` 标头与配置的多个格式匹配,则使用数组中的第一个匹配项。因此,数组顺序很重要。如果没有匹配项(或源图像为 动画),则图像优化 API 将回退到原始图像的格式。
如果未提供任何配置,则使用以下默认值。
module.exports = {
images: {
formats: ['image/webp'],
},
}
您可以启用 AVIF 支持,并仍然回退到 WebP,配置如下。
module.exports = {
images: {
formats: ['image/avif', 'image/webp'],
},
}
注意:与 WebP 相比,AVIF 的编码时间通常长 50%,但压缩尺寸小 20%。这意味着第一次请求图像时,通常会比较慢,然后缓存的后续请求会更快。
缓存行为
以下描述了默认 加载器 的缓存算法。对于所有其他加载器,请参阅您的云提供商的文档。
图像在请求时动态优化,并存储在 `<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 和浏览器。
- 您可以配置
minimumCacheTTL
以在上游图像不包含 `Cache-Control` 标头或其值非常低时增加缓存持续时间。 - 您可以配置
deviceSizes
和imageSizes
以减少可能生成的图像总数。 - 您可以配置 formats 以禁用多种格式,而只使用一种图像格式。
最小缓存 TTL
您可以配置缓存优化图像的生存时间 (TTL)(以秒为单位)。在许多情况下,最好使用 静态图像导入,它将自动散列文件内容并使用 `Cache-Control` 标头的 `immutable` 值永久缓存图像。
module.exports = {
images: {
minimumCacheTTL: 60,
},
}
优化图像的过期时间(或更确切地说是最大生存时间)由 `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
为真时,这一点尤其重要。
您可以选择配置 `inline` 以允许浏览器在直接访问时渲染图像,而无需下载它。
module.exports = {
images: {
contentDispositionType: 'inline',
},
}
动画图像
默认的 加载器 将自动绕过动画图像的图像优化,并按原样提供图像。
动画文件的自动检测是尽力而为的,支持 GIF、APNG 和 WebP。如果您想显式绕过给定动画图像的图像优化,请使用 unoptimized 属性。
版本历史
版本 | 更改 |
---|---|
v13.0.0 | next/image 重命名为 next/legacy/image |
这有帮助吗?