Skip to main content

Image(旧版)

从 Next.js 13 开始,next/image 组件被重写以改善性能和开发者体验。为了提供向后兼容的升级解决方案,旧的 next/image 被重命名为 next/legacy/image。

查看新的 next/image API 参考

对比​

与 next/legacy/image 相比,新的 next/image 组件有以下变化:

  • 移除 <img> 周围的 <span> 包裹,改用原生计算宽高比
  • 添加对规范 style prop 的支持
    • 移除 layout prop,改用 style 或 className
    • 移除 objectFit prop,改用 style 或 className
    • 移除 objectPosition prop,改用 style 或 className
  • 移除 IntersectionObserver 实现,改用原生懒加载
    • 移除 lazyBoundary prop,因为没有原生等效项
    • 移除 lazyRoot prop,因为没有原生等效项
  • 移除 loader 配置,改用 loader prop
  • 将 alt prop 从可选改为必需
  • 更改 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行为srcSetsizes是否有包裹器和尺寸器
intrinsic(默认)_缩小_以适应容器宽度,最大到图片尺寸1x、2x(基于 imageSizes)N/A是
fixed精确调整为 width 和 height1x、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:

next.config.js
module.exports = {
images: {
unoptimized: true,
},
}

其他 Props​

<Image /> 组件上的其他属性将传递给底层的 img 元素,但以下情况除外:

配置选项​

远程模式​

为了保护应用免受恶意用户的攻击,使用外部图片需要配置。这可确保只有来自你帐户的外部图片才能从 Next.js 图片优化 API 提供。这些外部图片可以使用 next.config.js 文件中的 remotePatterns 属性进行配置,如下所示:

next.config.js
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 属性示例:

next.config.js
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 属性示例:

next.config.js
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 属性的示例:

next.config.js
module.exports = {
images: {
domains: ['assets.acme.com'],
},
}

Loader 配置​

如果你想使用云提供商优化图片而不是使用 Next.js 内置的图片优化 API,可以在 next.config.js 文件中配置 loader 和 path 前缀。这允许你为 Image src 使用相对 URL,并自动为你的提供商生成正确的绝对 URL。

next.config.js
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 组件上实现 loader prop 来使用自定义云提供商

如果你需要不同的提供商,可以使用 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" 时,使用这些宽度以确保为用户设备提供正确的图片。

如果未提供配置,则使用以下默认值。

next.config.js
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 中的最小大小。

如果未提供配置,则使用以下默认值。

next.config.js
module.exports = {
images: {
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
},
}

可接受的格式​

默认的图片优化 API 将通过请求的 Accept 头自动检测浏览器支持的图片格式,以确定最佳输出格式。

如果 Accept 头匹配多个配置的格式,则使用数组中的第一个匹配项。因此,数组顺序很重要。如果没有匹配项(或源图片是动画),图片优化 API 将回退到原始图片的格式。

如果未提供配置,则使用以下默认值。

next.config.js
module.exports = {
images: {
formats: ['image/webp'],
},
}

你可以启用 AVIF 支持,如果浏览器不支持 AVIF,它将回退到 src 图片的原始格式:

next.config.js
module.exports = {
images: {
formats: ['image/avif'],
},
}

提示:

  • 我们仍然建议在大多数用例中使用 WebP。
  • AVIF 通常需要多 50% 的编码时间,但与 WebP 相比压缩率小 20%。这意味着第一次请求图片时通常会更慢,然后缓存的后续请求将更快。
  • 如果你在 Next.js 前面使用代理/CDN 进行自托管,则必须配置代理以转发 Accept 头。

缓存行为​

以下描述了默认 loader 的缓存算法。对于所有其他 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 和浏览器。

  • 你可以配置 minimumCacheTTL 以在上游图片不包含 Cache-Control 头或值非常低时增加缓存持续时间。
  • 你可以配置 deviceSizes 和 imageSizes 以减少可能生成的图片总数。
  • 你可以配置格式以禁用多种格式,改用单一图片格式。

最小缓存 TTL​

你可以为缓存的优化图片配置生存时间(TTL)(以秒为单位)。在许多情况下,最好使用静态图片导入,它会自动对文件内容进行哈希处理,并使用 immutable 的 Cache-Control 头永久缓存图片。

如果未提供配置,则使用以下默认值。

next.config.js
module.exports = {
images: {
minimumCacheTTL: 60, // 1 分钟
},
}

你可以增加 TTL 以减少重新验证的次数并可能降低成本:

next.config.js
module.exports = {
images: {
minimumCacheTTL: 2678400, // 31 天
},
}

优化图片的过期时间(或者说 Max Age)由 minimumCacheTTL 或上游图片的 Cache-Control 头定义,以较大者为准。

如果你需要更改每个图片的缓存行为,可以配置 headers 以在上游图片上设置 Cache-Control 头(例如 /some-asset.jpg,而不是 /_next/image 本身)。

目前没有机制使缓存失效,因此最好将 minimumCacheTTL 保持较低。否则,你可能需要手动更改 src prop 或删除 <distDir>/cache/images。

禁用静态导入​

默认行为允许你导入静态文件,例如 import icon from './icon.png',然后将其传递给 src 属性。

在某些情况下,如果此功能与其他期望导入行为不同的插件冲突,你可能希望禁用此功能。

你可以在 next.config.js 中禁用静态图片导入:

next.config.js
module.exports = {
images: {
disableStaticImages: true,
},
}

危险地允许 SVG​

默认 loader 出于几个原因不优化 SVG 图片。首先,SVG 是矢量格式,意味着它可以无损调整大小。其次,SVG 具有许多与 HTML/CSS 相同的功能,如果没有适当的内容安全策略(CSP)头,可能会导致漏洞。

因此,当 src prop 已知为 SVG 时,我们建议使用 unoptimized prop。当 src 以 ".svg" 结尾时,这会自动发生。

但是,如果你需要使用默认图片优化 API 提供 SVG 图片,可以在 next.config.js 中设置 dangerouslyAllowSVG:

next.config.js
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 以允许浏览器在直接访问时渲染图片,而无需下载。

next.config.js
module.exports = {
images: {
contentDispositionType: 'inline',
},
}

动画图片​

默认 loader 将自动绕过动画图片的图片优化,并按原样提供图片。

对动画文件的自动检测是尽力而为的,支持 GIF、APNG 和 WebP。如果你想明确绕过给定动画图片的图片优化,请使用 unoptimized prop。

版本历史​

版本变化
v13.0.0next/image 重命名为 next/legacy/image