Image(旧版)
从 Next.js 13 开始,next/image 组件被重写以改善性能和开发者体验。为了提供向后兼容的升级解决方案,旧的 next/image 被重命名为 next/legacy/image。
查看新的 next/image API 参考
对比
与 next/legacy/image 相比,新的 next/image 组件有以下变化:
- 移除
<img>周围的<span>包裹,改用原生计算宽高比 - 添加对规范
styleprop 的支持- 移除
layoutprop,改用style或className - 移除
objectFitprop,改用style或className - 移除
objectPositionprop,改用style或className
- 移除
- 移除
IntersectionObserver实现,改用原生懒加载- 移除
lazyBoundaryprop,因为没有原生等效项 - 移除
lazyRootprop,因为没有原生等效项
- 移除
- 移除
loader配置,改用loaderprop - 将
altprop 从可选改为必需 - 更改
onLoadingComplete回调以接收对<img>元素的引用
必需的 Props
<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" 的图片。
可选的 Props
<Image /> 组件除了必需属性外,还接受许多其他属性。本节描述 Image 组件最常用的属性。在高级 Props 部分中查找有关较少使用的属性的详细信息。
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 的自定义函数。将 loader 设置为 Image 组件上的 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 大小,从服务器选择的图片宽度将是所需宽度的 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 时,图片加载时不会有占位符,只有空白空间。
试试看:
高级 Props
在某些情况下,你可能需要更高级的用法。<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
在 src 图片成功加载之前用作占位符图片的 Data URL。仅在与 placeholder="blur" 结合使用时生效。
必须是 base64 编码的图片。它将被放大和模糊,因此建议使用非常小的图片(10px 或更小)。将较大的图片作为占位符可能会损害应用性能。
试试看:
你还可以生成纯色 Data 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 />
}
Since Next.js 12.3.0, this prop can be assigned to all images by updating next.config.js with the following configuration:
module.exports = {
images: {
unoptimized: true,
},
}
其他 Props
<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。
Domains
警告:自 Next.js 14 起已弃用,建议使用严格的
remotePatterns以保护应用免受恶意用户的攻击。只有在你拥有从该域提供的所有内容时才使用domains。
与 remotePatterns 类似,domains 配置可用于提供外部图片的允许主机名列表。
但是,domains 配置不支持通配符模式匹配,并且不能限制协议、端口或路径名。
以下是 next.config.js 文件中 domains 属性的示例:
module.exports = {
images: {
domains: ['assets.acme.com'],
},
}
Loader 配置
如果你想使用云提供商优化图片而不是使用 Next.js 内置的图片优化 API,可以在 next.config.js 文件中配置 loader 和 path 前缀。这允许你为 Image src 使用相对 URL,并自动为你的提供商生成正确的绝对 URL。
module.exports = {
images: {
loader: 'imgix',
path: 'https://example.com/myaccount/',
},
}
内置 Loaders
包含以下图片优化云提供商:
- 默认:自动与
next dev、next start或自定义服务器配合使用 - Vercel:在 Vercel 上部署时自动工作,无需配置。了解更多
- Imgix:
loader: 'imgix' - Cloudinary:
loader: 'cloudinary' - Akamai:
loader: 'akamai' - 自定义:
loader: 'custom'通过在next/legacy/image组件上实现loaderprop 来使用自定义云提供商
如果你需要不同的提供商,可以使用 next/legacy/image 的 loader prop。
使用
output: 'export'时,图片无法在构建时优化,只能按需优化。要将next/legacy/image与output: 'export'一起使用,你需要使用与默认不同的 loader。在讨论中阅读更多。
高级配置
以下配置适用于高级用例,通常不是必需的。如果你选择配置以下属性,你将覆盖未来更新中对 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 prop 的图片,这表明图片小于屏幕的全宽。因此,imageSizes 中的大小都应小于 deviceSizes 中的最小大小。
如果未提供配置,则使用以下默认值。
module.exports = {
images: {
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
},
}