<Image>(旧版)

示例

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

查看新版 next/image API 参考文档

对比

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

  • 移除了 <img> 外层的 <span> 包装,改用原生计算宽高比
  • 新增对标准 style 属性的支持
    • 移除 layout 属性,改用 styleclassName
    • 移除 objectFit 属性,改用 styleclassName
    • 移除 objectPosition 属性,改用 styleclassName
  • 移除 IntersectionObserver 实现,改用原生懒加载
    • 移除 lazyBoundary 属性(无原生等效方案)
    • 移除 lazyRoot 属性(无原生等效方案)
  • 移除 loader 配置,改用 loader 属性
  • alt 属性从可选改为必填
  • 修改 onLoadingComplete 回调参数为 <img> 元素的引用

必填属性

<Image /> 组件需要以下属性。

src

必须是以下之一:

使用外部 URL 时,必须将其添加到 next.config.jsremotePatterns 中。

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)不适用
fixed严格按 widthheight 尺寸显示1x, 2x (基于 imageSizes)不适用
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

优化图片的质量,整数范围从 1100100 为最佳质量。默认为 75

priority

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

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

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

placeholder

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

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

对于动态图片,你必须提供 blurDataURL 属性。可以使用 Plaiceholder 等工具帮助生成 base64

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

尝试以下示例:

高级属性

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

style

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

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

同时记住,必填的 widthheight 属性可能与你的样式交互。如果使用样式修改图片的 width,必须同时设置 height="auto" 样式,否则图片会变形。

objectFit

定义当使用 layout="fill" 时图片如何适应其父容器。

此值传递给 src 图片的 object-fit CSS 属性

objectPosition

定义当使用 layout="fill" 时图片在其父元素中的定位方式。

此值传递给应用于图片的 object-position CSS 属性

onLoadingComplete

一个回调函数,在图片完全加载且占位符被移除后调用。

onLoadingComplete 函数接收一个参数,包含以下属性的对象:

loading

注意:此属性仅用于高级用法。将图片切换为 eager 加载通常会损害性能

我们建议改用 priority 属性,它能正确处理几乎所有用例的急切加载。

图片的加载行为。默认为 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 时,源图像将按原样提供,不会改变质量、尺寸或格式。默认为 false

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 元素,但以下属性除外:

配置选项

远程模式 (Remote Patterns)

为了保护您的应用免受恶意用户攻击,使用外部图像时需要配置。这确保只有您账户的外部图像可以通过 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 Configuration)

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

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

内置加载器 (Built-in Loaders)

以下图像优化云提供商已内置支持:

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

如果您需要其他提供商,可以在 next/legacy/image 上使用 loader 属性。

使用 output: 'export' 时,图像无法在构建时优化,只能按需优化。要将 next/legacy/imageoutput: 'export' 一起使用,您需要使用非默认的加载器。在讨论中了解更多。

next/legacy/image 组件的默认加载器使用 squoosh,因为它安装快速且适合开发环境。在生产环境中使用 next start 时,强烈建议通过运行 npm i sharp 在项目目录中安装 sharp。对于 Vercel 部署,无需手动安装,因为 sharp 会自动安装。

高级配置

以下配置适用于高级用例,通常不需要。如果您选择配置以下属性,将覆盖未来更新中对 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 属性指定图像宽度列表。这些宽度与 设备尺寸 (Device Sizes) 数组连接,形成用于生成图像 srcset 的完整尺寸数组。

之所以有两个独立的列表,是因为 imageSizes 仅用于提供 sizes 属性的图像,这些图像的宽度小于屏幕的完整宽度。因此,imageSizes 中的尺寸应全部小于 deviceSizes 中的最小尺寸。

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

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

可接受的格式 (Acceptable Formats)

默认的 图像优化 API (Image Optimization API) 会通过请求的 Accept 标头自动检测浏览器支持的图像格式。

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

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

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

您可以通过以下配置启用 AVIF 支持:

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

须知:AVIF 编码通常比 WebP 多花 20% 的时间,但压缩率比 WebP 高 20%。这意味着首次请求图像时通常会较慢,但后续缓存的请求会更快。

缓存行为

以下描述了默认 加载器 (loader) 的缓存算法。对于所有其他加载器,请参阅您的云提供商的文档。

图像在请求时动态优化,并存储在 <distDir>/cache/images 目录中。优化后的图像文件将在后续请求中提供服务,直到过期。当请求匹配缓存但已过期的文件时,会立即提供过期的图像。然后在后台重新优化图像(也称为重新验证),并使用新的过期日期保存到缓存中。

可以通过读取 x-nextjs-cache(部署在 Vercel 时为 x-vercel-cache)响应标头的值来确定图像的缓存状态。可能的值如下:

  • MISS - 路径不在缓存中(最多发生一次,首次访问时)
  • STALE - 路径在缓存中,但已超过重新验证时间,因此将在后台更新
  • HIT - 路径在缓存中,且未超过重新验证时间

过期时间(或更准确地说,最大寿命)由 minimumCacheTTL 配置或上游图像的 Cache-Control 标头中的较大者定义。具体来说,使用 Cache-Control 标头的 max-age 值。如果同时找到 s-maxagemax-age,则优先使用 s-maxagemax-age 也会传递给任何下游客户端,包括 CDN 和浏览器。

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

最小缓存 TTL (Minimum Cache TTL)

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

next.config.js
module.exports = {
  images: {
    minimumCacheTTL: 60,
  },
}

优化图像的过期时间(或更准确地说,最大寿命)由 minimumCacheTTL 或上游图像的 Cache-Control 标头中的较大者定义。

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

目前没有机制可以手动使缓存失效,因此最好将 minimumCacheTTL 设置为较低的值。否则,您可能需要手动更改 src 属性或删除 <distDir>/cache/images

禁用静态导入 (Disable Static Imports)

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

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

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

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

危险地允许 SVG (Dangerously Allow SVG)

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

因此,当 src 属性已知为 SVG 时,我们建议使用 unoptimized 属性。当 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 以防止嵌入在图像中的脚本执行。

动画图像 (Animated Images)

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

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

版本历史

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