跳到主要内容

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,改用 styleclassName
    • 移除 objectFit prop,改用 styleclassName
    • 移除 objectPosition prop,改用 styleclassName
  • 移除 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 格式时,除非启用 unoptimizeddangerouslyAllowSVG,否则将被阻止

width

width 属性可以表示_渲染_宽度或_原始_宽度(以像素为单位),具体取决于 layoutsizes 属性。

使用 layout="intrinsic"layout="fixed" 时,width 属性表示_渲染_宽度(以像素为单位),因此会影响图片显示的大小。

使用 layout="responsive"layout="fill" 时,width 属性表示_原始_宽度(以像素为单位),因此只会影响宽高比。

width 属性是必需的,除非是静态导入的图片或具有 layout="fill" 的图片。

height

height 属性可以表示_渲染_高度或_原始_高度(以像素为单位),具体取决于 layoutsizes 属性。

使用 layout="intrinsic"layout="fixed" 时,height 属性表示_渲染_高度(以像素为单位),因此会影响图片显示的大小。

使用 layout="responsive"layout="fill" 时,height 属性表示_原始_高度(以像素为单位),因此只会影响宽高比。

height 属性是必需的,除非是静态导入的图片或具有 layout="fill" 的图片。

可选的 Props

<Image /> 组件除了必需属性外,还接受许多其他属性。本节描述 Image 组件最常用的属性。在高级 Props 部分中查找有关较少使用的属性的详细信息。

layout

图片在视口大小变化时的布局行为。

layout行为srcSetsizes是否有包裹器和尺寸器
intrinsic(默认)_缩小_以适应容器宽度,最大到图片尺寸1x2x(基于 imageSizesN/A
fixed精确调整为 widthheight1x2x(基于 imageSizesN/A
responsive缩放以适应容器宽度640w750w、... 2048w3840w(基于 imageSizesdeviceSizes100vw
fill在 X 和 Y 轴上增长以填充容器640w750w、... 2048w3840w(基于 imageSizesdeviceSizes100vw
  • 演示 intrinsic 布局(默认)
    • 使用 intrinsic 时,图片会为较小的视口缩小尺寸,但为较大的视口保持原始尺寸。
  • 演示 fixed 布局
    • 使用 fixed 时,图片尺寸不会随着视口变化而改变(无响应性),类似于原生 img 元素。
  • 演示 responsive 布局
    • 使用 responsive 时,图片会为较小的视口缩小尺寸,为较大的视口放大。
    • 确保父元素在样式表中使用 display: block
  • 演示 fill 布局
    • 使用 fill 时,图片会拉伸宽度和高度以适应父元素的尺寸,前提是父元素是相对定位的。
    • 这通常与 objectFit 属性配对使用。
    • 确保父元素在样式表中具有 position: relative
  • 演示背景图片

loader

用于解析 URL 的自定义函数。将 loader 设置为 Image 组件上的 prop 会覆盖 next.config.jsimages 部分中定义的默认 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 倍的图片。

了解更多关于 srcsetsizes 的信息:

quality

优化图片的质量,是一个介于 1100 之间的整数,其中 100 是最佳质量。默认为 75

priority

当为 true 时,图片将被视为高优先级并预加载。对于使用 priority 的图片,懒加载会自动禁用。

你应该在检测到的任何作为最大内容绘制(LCP)元素的图片上使用 priority 属性。可能适合有多个优先级图片,因为不同的图片可能是不同视口大小的 LCP 元素。

仅当图片在首屏可见时才应使用。默认为 false

placeholder

图片加载时使用的占位符。可能的值是 blurempty。默认为 empty

当为 blur 时,blurDataURL 属性将用作占位符。如果 src 是来自静态导入的对象,并且导入的图片是 .jpg.png.webp.avif,那么 blurDataURL 将自动填充。

对于动态图片,你必须提供 blurDataURL 属性。诸如 Plaiceholder 之类的解决方案可以帮助生成 base64

当为 empty 时,图片加载时不会有占位符,只有空白空间。

试试看:

高级 Props

在某些情况下,你可能需要更高级的用法。<Image /> 组件可选地接受以下高级属性。

style

允许向底层图片元素传递 CSS 样式

请注意,所有 layout 模式都会对图片元素应用自己的样式,这些自动样式优先于 style prop。

还要记住,必需的 widthheight 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/imagesrc 属性必须以 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/imagesrc 属性必须以 https://img1.example.comhttps://me.avatar.example.com 或任意数量的子域开头。它不能有端口或查询字符串。任何其他协议或不匹配的主机名都将响应 400 Bad Request。

通配符模式可用于 pathnamehostname,并具有以下语法:

  • * 匹配单个路径段或子域
  • ** 匹配末尾的任意数量的路径段或开头的子域

** 语法在模式中间不起作用。

提示:当省略 protocolportpathnamesearch 时,将隐含通配符 **。不建议这样做,因为它可能允许恶意行为者优化你不打算优化的 URL。

以下是在 next.config.js 文件中使用 searchremotePatterns 属性示例:

next.config.js
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'assets.example.com',
search: '?v=1727111025337',
},
],
},
}

提示:上面的示例将确保 next/legacy/imagesrc 属性必须以 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 文件中配置 loaderpath 前缀。这允许你为 Image src 使用相对 URL,并自动为你的提供商生成正确的绝对 URL。

next.config.js
module.exports = {
images: {
loader: 'imgix',
path: 'https://example.com/myaccount/',
},
}

内置 Loaders

包含以下图片优化云提供商:

  • 默认:自动与 next devnext start 或自定义服务器配合使用
  • Vercel:在 Vercel 上部署时自动工作,无需配置。了解更多
  • Imgixloader: 'imgix'
  • Cloudinaryloader: 'cloudinary'
  • Akamailoader: 'akamai'
  • 自定义:loader: 'custom' 通过在 next/legacy/image 组件上实现 loader prop 来使用自定义云提供商

如果你需要不同的提供商,可以使用 next/legacy/imageloader prop。

使用 output: 'export' 时,图片无法在构建时优化,只能按需优化。要将 next/legacy/imageoutput: '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-maxagemax-age,则首选 s-maxagemax-age 也会传递给任何下游客户端,包括 CDN 和浏览器。

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

最小缓存 TTL

你可以为缓存的优化图片配置生存时间(TTL)(以秒为单位)。在许多情况下,最好使用静态图片导入,它会自动对文件内容进行哈希处理,并使用 immutableCache-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

默认 loaderContent-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