跳到内容
API 参考组件图像 (旧版)

Image (旧版)

示例

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

查看新的 next/image API 参考

比较

next/legacy/image 相比,新的 next/image 组件有以下更改

  • 移除 <span> 包装器,围绕 <img>,转而使用 原生计算的宽高比
  • 添加对规范 style 属性的支持
    • 移除 layout 属性,转而使用 styleclassName
    • 移除 objectFit 属性,转而使用 styleclassName
    • 移除 objectPosition 属性,转而使用 styleclassName
  • 移除 IntersectionObserver 实现,转而使用 原生懒加载
    • 移除 lazyBoundary 属性,因为没有原生等效项
    • 移除 lazyRoot 属性,因为没有原生等效项
  • 移除 loader 配置,转而使用 loader 属性
  • alt 属性从可选更改为必需
  • 更改 onLoadingComplete 回调以接收对 <img> 元素的引用

必需属性

<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" 的图像。

可选属性

<Image /> 组件接受许多必需属性之外的其他属性。本节介绍 Image 组件最常用的属性。在高级属性部分查找有关较少使用的属性的详细信息。

layout

图像在视口大小更改时的布局行为。

layout行为srcSetsizes有包装器和尺寸调整器
intrinsic (默认)向下缩放到容器宽度,最大为图像尺寸1x, 2x (基于 imageSizes)N/A
fixed精确调整为 widthheight1x, 2x (基于 imageSizes)N/A
responsive缩放以适应容器宽度640w, 750w, ... 2048w, 3840w (基于 imageSizesdeviceSizes)100vw
fill在 X 轴和 Y 轴上扩展以填充容器640w, 750w, ... 2048w, 3840w (基于 imageSizesdeviceSizes)100vw
  • 演示 intrinsic 布局 (默认)
    • 当为 intrinsic 时,图像将缩小尺寸以适应较小的视口,但对于较大的视口,则保持原始尺寸。
  • 演示 fixed 布局
    • 当为 fixed 时,图像尺寸不会随着视口的变化而变化(没有响应式),类似于原生 img 元素。
  • 演示 responsive 布局
    • 当为 responsive 时,图像将缩小尺寸以适应较小的视口,并放大尺寸以适应较大的视口。
    • 确保父元素在其样式表中使用 display: block
  • 演示 fill 布局
    • 当为 fill 时,图像将拉伸宽度和高度以适应父元素的尺寸,前提是父元素是相对定位的。
    • 这通常与 objectFit 属性配对使用。
    • 确保父元素在其样式表中使用 position: relative
  • 演示背景图像

loader

用于解析 URL 的自定义函数。在 Image 组件上设置 loader 作为属性会覆盖在 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

一个字符串,提供有关图像在不同断点处的宽度的信息。对于使用 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 倍的图像。

了解更多关于 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 时,图像加载时将没有占位符,只有空白空间。

尝试一下

高级属性

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

样式

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

请注意,所有 layout 模式都会将它们自身的样式应用于图像元素,并且这些自动样式优先于 style 属性。

另请记住,必需的 widthheight 属性可能会与您的样式交互。如果您使用样式来修改图像的 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 将此属性分配给所有图像

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

其他属性

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

配置选项

远程模式

为了保护您的应用程序免受恶意用户的攻击,需要进行配置才能使用外部图像。这确保只有来自您帐户的外部图像才能从 Next.js Image Optimization 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。

域名

警告:自 Next.js 14 起已弃用,建议使用严格的 remotePatterns 以保护您的应用程序免受恶意用户的攻击。仅当您拥有从域提供的所有内容时才使用 domains

remotePatterns 类似,domains 配置可用于提供外部图像的允许主机名列表。

但是,domains 配置不支持通配符模式匹配,并且不能限制协议、端口或路径名。

下面是 next.config.js 文件中 domains 属性的示例

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

加载器配置

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

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

内置加载器

包含以下 Image Optimization 云提供商:

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

如果您需要其他提供商,可以使用带有 next/legacy/imageloader 属性。

图像无法在使用 output: 'export' 的构建时进行优化,只能按需优化。要将 next/legacy/imageoutput: 'export' 一起使用,您将需要使用与默认值不同的加载器。在讨论中阅读更多内容。

高级

以下配置适用于高级用例,通常不是必需的。如果您选择配置以下属性,您将覆盖未来更新中对 Next.js 默认值的任何更改。

设备尺寸

如果您知道用户的预期设备宽度,则可以使用 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],
  },
}

图像尺寸

您可以使用 next.config.js 文件中的 images.imageSizes 属性指定图像宽度列表。这些宽度与设备尺寸数组连接,形成用于生成图像 srcsets 的完整尺寸数组。

存在两个单独列表的原因是 imageSizes 仅用于提供 sizes 属性的图像,这表明图像小于屏幕的完整宽度。因此,imageSizes 中的尺寸都应小于 deviceSizes 中最小的尺寸。

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

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

可接受的格式

默认的 Image Optimization API 将自动检测浏览器支持的图像格式,通过请求的 Accept 标头来确定最佳输出格式。

如果 Accept 标头匹配多个配置的格式,则使用数组中的第一个匹配项。因此,数组顺序很重要。如果没有匹配项(或者源图像是动画),Image Optimization 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% 更小的尺寸。这意味着首次请求图像时,通常会较慢,然后后续缓存的请求会更快。
  • 如果您使用 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-maxagemax-age,则首选 s-maxagemax-age 也传递给任何下游客户端,包括 CDN 和浏览器。

  • 当上游图像不包含 Cache-Control 标头或该值非常低时,您可以配置 minimumCacheTTL 以增加缓存持续时间。
  • 您可以配置 deviceSizesimageSizes 以减少可能生成的图像总数。
  • 您可以配置 formats 以禁用多种格式,而只支持单一图像格式。

最小缓存 TTL

您可以配置缓存优化图像的生存时间 (TTL),以秒为单位。在许多情况下,最好使用静态图像导入,这将自动哈希文件内容,并使用 immutableCache-Control 标头永久缓存图像。

next.config.js
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 中禁用静态图像导入

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

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',
  },
}

动画图像

默认的 加载器 将自动绕过动画图像的图像优化,并按原样提供图像。

自动检测动画文件是尽力而为,并支持 GIF、APNG 和 WebP。如果您想为给定的动画图像显式绕过图像优化,请使用 unoptimized 属性。

版本历史

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