跳到内容
API 参考组件Image (Legacy)

Image (Legacy)

这是一个旧版 API,不再推荐使用。为了向后兼容性,它仍然受支持。

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

警告:`next/legacy/image` 已弃用,并将在未来的 Next.js 版本中移除。请改用 `next/image`

比较

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

  • 移除 `<img>` 周围的 `<span>` 包装器,转而使用 原生计算宽高比
  • 新增对标准 `style` 属性的支持
    • 移除 `layout` 属性,转而使用 `style` 或 `className`
    • 移除 `objectFit` 属性,转而使用 `style` 或 `className`
    • 移除 `objectPosition` 属性,转而使用 `style` 或 `className`
  • 移除 `IntersectionObserver` 实现,转而使用 原生延迟加载
    • 移除 `lazyBoundary` 属性,因为没有原生等效项
    • 移除 `lazyRoot` 属性,因为没有原生等效项
  • 移除 `loader` 配置,转而使用 `loader` 属性
  • 将 `alt` 属性从可选改为必填
  • 将 `onLoadingComplete` 回调更改为接收 `<img>` 元素的引用

必需属性

Image 组件需要以下属性。

src

必须是以下之一:

使用默认 加载器 时,还应考虑源图片的以下情况:

  • 当 src 为外部 URL 时,您还必须配置 remotePatterns
  • 当 src 为动画或未知格式(JPEG、PNG、WebP、AVIF、GIF、TIFF)时,图片将按原样提供
  • 当 src 为 SVG 格式时,除非启用 `unoptimized` 或 `dangerouslyAllowSVG`,否则将被阻止

宽度

`width` 属性可以表示像素的*渲染*宽度或*原始*宽度,具体取决于 `layout``sizes` 属性。

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

当使用 `layout="responsive"`、`layout="fill"` 时,`width` 属性表示以像素为单位的*原始*宽度,因此它只会影响宽高比。

除了静态导入的图片或 `layout="fill"` 的图片外,`width` 属性是必需的。

高度

`height` 属性可以表示像素的*渲染*高度或*原始*高度,具体取决于 `layout``sizes` 属性。

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

当使用 `layout="responsive"`、`layout="fill"` 时,`height` 属性表示以像素为单位的*原始*高度,因此它只会影响宽高比。

除了静态导入的图片或 `layout="fill"` 的图片外,`height` 属性是必需的。

可选属性

Image 组件除了必需的属性外,还接受许多附加属性。本节介绍 Image 组件最常用的属性。有关不常用属性的详细信息,请参见高级属性部分。

布局

当视口尺寸改变时,图像的布局行为。

布局行为srcSet尺寸有包装器和尺寸器
固有(默认)缩小以适应容器宽度,最大不超过图像尺寸1x,2x(基于图像尺寸不适用
固定精确调整为 `width` 和 `height`1x,2x(基于图像尺寸不适用
响应式按比例缩放以适应容器宽度640w、750w、... 2048w、3840w(基于图像尺寸设备尺寸100vw
填充在X和Y轴上同时增长以填充容器640w、750w、... 2048w、3840w(基于图像尺寸设备尺寸100vw
  • 演示 `intrinsic` 布局(默认)
    • 当 `intrinsic` 时,图片会针对较小的视口缩小尺寸,但对于较大的视口则保持原始尺寸。
  • 演示 `fixed` 布局
    • 当 `fixed` 时,图像尺寸不会随视口变化而改变(无响应性),类似于原生 `img` 元素。
  • 演示 `responsive` 布局
    • 当 `responsive` 时,图像会针对较小的视口缩小尺寸,并针对较大的视口放大尺寸。
    • 请确保父元素在其样式表中使用了 `display: block`。
  • 演示 `fill` 布局
    • 当 `fill` 时,图像的宽度和高度都将拉伸至父元素的尺寸,前提是父元素是相对定位的。
    • 这通常与 `objectFit` 属性搭配使用。
    • 确保父元素在其样式表中具有 `position: relative`。
  • 演示背景图片

加载器

一个用于解析 URL 的自定义函数。在 Image 组件上将加载器设置为属性会覆盖 `next.config.js` 中`images` 部分定义的默认加载器。

`loader` 是一个函数,给定以下参数,返回图像的 URL 字符串:

这是一个使用自定义加载器的示例:

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}
    />
  )
}

尺寸

一个字符串,提供关于图像在不同断点处的宽度信息。对于使用 `layout="responsive"` 或 `layout="fill"` 的图像,`sizes` 的值将极大地影响性能。对于使用 `layout="intrinsic"` 或 `layout="fixed"` 的图像,它将被忽略。

`sizes` 属性在图像性能方面具有两个重要目的:

首先,`sizes` 的值被浏览器用于确定要从 `next/legacy/image` 自动生成的源集中下载哪种尺寸的图像。当浏览器选择时,它还不知道页面上图像的大小,因此它选择一个与视口大小相同或更大的图像。`sizes` 属性允许您告诉浏览器图像实际上会小于全屏。如果您未指定 `sizes` 值,则使用默认值 `100vw`(全屏宽度)。

其次,解析并使用 `sizes` 值来修剪自动创建的源集中的值。如果 `sizes` 属性包含 `50vw` 等大小,这些大小表示视口宽度的百分比,则会修剪源集,使其不包含任何太小而无需的值。

例如,如果您知道您的样式会导致图像在移动设备上全宽显示,在平板电脑上采用两列布局,在桌面显示器上采用三列布局,您应该包含一个 `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` 的更多信息

质量

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

优先级

当为 true 时,图像将被视为高优先级并进行预加载。对于使用 `priority` 的图像,延迟加载会自动禁用。

您应该对任何被检测为 最大内容绘制 (LCP) 元素的图像使用 `priority` 属性。可能适合使用多个优先级图像,因为不同的图像可能是不同视口尺寸的 LCP 元素。

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

占位符

在图像加载期间使用的占位符。可能的值为 `blur` 或 `empty`。默认为 `empty`。

当设置为 `blur` 时,`blurDataURL` 属性将用作占位符。如果 `src` 是来自静态导入的对象,并且导入的图像是 `.jpg`、`.png`、`.webp` 或 `.avif` 格式,则 `blurDataURL` 将自动填充。

对于动态图片,您必须提供 `blurDataURL` 属性。像 Plaiceholder 等解决方案可以帮助生成 `base64`。

当 `empty` 时,图像加载时不会有占位符,只有空白区域。

尝试一下

高级属性

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

样式

允许将 CSS 样式 传递给底层图像元素。

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

另请记住,必需的 `width` 和 `height` 属性可以与您的样式相互作用。如果您使用样式修改图像的 `width`,则还必须设置 `height="auto"` 样式,否则您的图像将变形。

objectFit

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

此值被传递给 `src` 图像的 object-fit CSS 属性

objectPosition

在使用 `layout="fill"` 时,定义图像在其父元素中的位置。

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

onLoadingComplete

图像完全加载且占位符已移除后调用的回调函数。

`onLoadingComplete` 函数接受一个参数,该参数是一个具有以下属性的对象:

加载

图像的加载行为。默认为 `lazy`。

当 `lazy` 时,延迟加载图像直到其到达距离视口的计算距离。

当 `eager` 时,立即加载图像。

了解更多

blurDataURL

在 `src` 图像成功加载之前用作占位符图像的 数据 URL。仅当与 `placeholder="blur"` 结合使用时才生效。

必须是 base64 编码的图像。它将被放大和模糊,因此建议使用非常小的图像(10 像素或更小)。包含较大的图像作为占位符可能会损害您的应用程序性能。

尝试一下

您还可以生成纯色数据 URL 以匹配图像。

lazyBoundary

一个字符串(语法类似于 `margin` 属性),充当用于检测视口与图像交集并触发延迟加载的边界框。默认为 `"200px"`。

如果图像嵌套在除根文档之外的可滚动父元素中,您还需要分配 lazyRoot 属性。

了解更多

lazyRoot

指向可滚动父元素的 React 引用。默认为 `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>
  )
}

了解更多

未优化

当为 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 图像优化 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。

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

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

`**` 语法不适用于模式的中间部分。

温馨提示:省略 protocolportpathnamesearch 时,隐含通配符 **。不建议这样做,因为它可能允许恶意行为者优化您不希望优化的 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。

域名

警告:自 Next.js 14 起已弃用,转而采用严格的 `remotePatterns`,以保护您的应用程序免受恶意用户侵害。仅当您拥有该域名提供的所有内容时才使用 `domains`。

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

但是,`domains` 配置不支持通配符模式匹配,也无法限制协议、端口或路径名。

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

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

加载器配置

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

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

自定义内置图片路径

如果您想更改或为内置 Next.js 图像优化添加前缀,可以使用 `path` 属性进行操作。`path` 的默认值为 `/_next/image`。

next.config.js
module.exports = {
  images: {
    path: '/my-prefix/_next/image',
  },
}

内置加载器

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

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

如果您需要其他提供商,可以将 `loader` 属性与 `next/legacy/image` 一起使用。

图片无法在构建时使用 `output: 'export'` 进行优化,只能按需优化。要将 `next/legacy/image` 与 `output: '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` 属性指定图像宽度列表。这些宽度与设备尺寸数组连接,形成用于生成图像 srcset 的完整尺寸数组。

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

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

next.config.js
module.exports = {
  images: {
    imageSizes: [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%。这意味着图像首次请求时通常会更慢,然后后续缓存的请求会更快。
  • 如果您使用 Proxy/CDN 在 Next.js 前面进行自托管,则必须配置 Proxy 以转发 Accept 头部。

缓存行为

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

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

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

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

过期时间(或更确切地说是最大存活期)由 `minimumCacheTTL` 配置或上游图像 `Cache-Control` 标头定义,以两者中较大的为准。具体来说,使用 `Cache-Control` 标头的 `max-age` 值。如果同时找到 `s-maxage` 和 `max-age`,则首选 `s-maxage`。`max-age` 也传递给包括 CDN 和浏览器在内的任何下游客户端。

  • 当上游图片不包含 `Cache-Control` 标头或其值很低时,您可以配置 `minimumCacheTTL` 来增加缓存持续时间。
  • 您可以配置 `deviceSizes``imageSizes` 以减少可能生成的图像总数。
  • 您可以配置 formats 以禁用多种格式,转而使用单一图像格式。

最小缓存 TTL

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

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

next.config.js
module.exports = {
  images: {
    minimumCacheTTL: 14400, // 4 hours
  },
}

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

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

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

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

目前还没有机制来使缓存失效,因此最好将 `minimumCacheTTL` 保持在较低水平。否则,您可能需要手动更改 `src` 属性或删除 `<distDir>/cache/images`。

禁用静态导入

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

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

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

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

危险地允许 SVG

默认的加载器不优化 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 以防止嵌入图像中的脚本执行。

contentDispositionType

默认的加载器`Content-Disposition` 标头设置为 `attachment`,以增加保护,因为 API 可以提供任意远程图像。

默认值为 `attachment`,它强制浏览器在直接访问时下载图像。当 `dangerouslyAllowSVG` 为 true 时,这一点尤为重要。

您可以选择配置 inline,以允许浏览器在直接访问时呈现图像,而无需下载。

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

动画图像

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

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

版本历史

版本更改
v16.0.0`next/legacy/image` 已弃用,并将在未来的 Next.js 版本中移除。请改用 `next/image`。
v13.0.0`next/image` 重命名为 `next/legacy/image`