跳到内容

Image

示例

须知:如果您使用的是 13 之前的 Next.js 版本,您需要使用 next/legacy/image 文档,因为该组件已重命名。

此 API 参考将帮助您了解如何使用 Image 组件的 props配置选项。有关功能和用法,请参阅 Image 组件页面。

app/page.js
import Image from 'next/image'
 
export default function Page() {
  return (
    <Image
      src="/profile.png"
      width={500}
      height={500}
      alt="Picture of the author"
    />
  )
}

Props

这是 Image 组件可用 props 的摘要

Prop示例类型状态
srcsrc="/profile.png"String必需
widthwidth={500}整数 (px)必需
heightheight={500}整数 (px)必需
altalt="作者的照片"String必需
loaderloader={imageLoader}Function-
fillfill={true}Boolean-
sizessizes="(max-width: 768px) 100vw, 33vw"String-
qualityquality={80}整数 (1-100)-
prioritypriority={true}Boolean-
placeholderplaceholder="blur"String-
stylestyle={{objectFit: "contain"}}Object-
onLoadingCompleteonLoadingComplete={img => done())}Function已弃用
onLoadonLoad={event => done())}Function-
onErroronError(event => fail()}Function-
loadingloading="lazy"String-
blurDataURLblurDataURL="data:image/jpeg..."String-
overrideSrcoverrideSrc="/seo.png"String-

必需的 Props

Image 组件需要以下属性:srcaltwidthheight(或 fill)。

app/page.js
import Image from 'next/image'
 
export default function Page() {
  return (
    <div>
      <Image
        src="/profile.png"
        width={500}
        height={500}
        alt="Picture of the author"
      />
    </div>
  )
}

src

必须是以下之一

  • 一个 静态导入的 图像文件
  • 路径字符串。这可以是绝对外部 URL,也可以是内部路径,具体取决于 loader prop。

当使用默认 loader 时,还要考虑源图像的以下事项

  • 当 src 是外部 URL 时,您还必须配置 remotePatterns
  • 当 src 是 动画或不是已知格式(JPEG、PNG、WebP、AVIF、GIF、TIFF)时,图像将按原样提供
  • 当 src 是 SVG 格式时,它将被阻止,除非启用 unoptimizeddangerouslyAllowSVG

width

width 属性表示图像的固有宽度(以像素为单位)。此属性用于推断图像的正确宽高比,并避免加载期间的布局偏移。它不决定图像的渲染大小,图像的渲染大小由 CSS 控制,类似于 HTML <img> 标签中的 width 属性。

必需,静态导入的图像或具有 fill 属性的图像除外。

height

height 属性表示图像的固有高度(以像素为单位)。此属性用于推断图像的正确宽高比,并避免加载期间的布局偏移。它不决定图像的渲染大小,图像的渲染大小由 CSS 控制,类似于 HTML <img> 标签中的 height 属性。

必需,静态导入的图像或具有 fill 属性的图像除外。

须知

  • widthheight 属性结合使用,以确定图像的宽高比,浏览器使用该宽高比在图像加载之前为图像预留空间。
  • 固有大小并不总是意味着浏览器中的渲染大小,渲染大小将由父容器决定。例如,如果父容器小于固有大小,则图像将被缩小以适应容器。
  • widthheight 未知时,您可以使用 fill 属性。

alt

alt 属性用于为屏幕阅读器和搜索引擎描述图像。如果图像已被禁用或在加载图像时发生错误,它也是回退文本。

它应该包含可以替换图像的文本,而 不会改变页面的含义。它不是为了补充图像,不应重复图像上方或下方标题中已提供的信息。

如果图像纯粹是 装饰性的不打算给用户使用,则 alt 属性应为空字符串 (alt="")。

了解更多

可选的 Props

<Image /> 组件接受许多必需属性之外的其他属性。本节介绍 Image 组件最常用的属性。有关不太常用属性的详细信息,请参阅高级 Props部分。

loader

用于解析图像 URL 的自定义函数。

loader 是一个函数,它为图像返回一个 URL 字符串,并提供以下参数

这是一个使用自定义 loader 的示例

import Image from 'next/image'
 
const imageLoader = ({ src, width, quality }) => {
  return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}
 
export default function Page() {
  return (
    <Image
      loader={imageLoader}
      src="me.png"
      alt="Picture of the author"
      width={500}
      height={500}
    />
  )
}

或者,您可以使用 next.config.js 中的 loaderFile 配置来配置应用程序中 next/image 的每个实例,而无需传递 prop。

fill

fill={true} // {true} | {false}

一个布尔值,使图像填充父元素,当 widthheight 未知时,这很有用。

父元素必须分配 position: "relative"position: "fixed"position: "absolute" 样式。

默认情况下,img 元素将自动分配 position: "absolute" 样式。

如果没有样式应用于图像,则图像将拉伸以适应容器。您可能更喜欢为图像设置 object-fit: "contain",该图像将被信箱化以适应容器并保留宽高比。

或者,object-fit: "cover" 将使图像填充整个容器并被裁剪以保留宽高比。

有关更多信息,另请参阅

sizes

一个字符串,类似于媒体查询,提供有关图像在不同断点处的宽度的信息。对于使用 fill 或样式设置为具有响应式大小的图像,sizes 的值将极大地影响性能。

sizes 属性服务于与图像性能相关的两个重要目的

  • 首先,浏览器使用 sizes 的值来确定要下载的图像大小,从 next/image 自动生成的 srcset 中。当浏览器选择时,它还不知道页面上图像的大小,因此它选择与视口大小相同或更大的图像。sizes 属性允许您告诉浏览器图像实际上会小于全屏。如果您在使用 fill 属性的图像中未指定 sizes 值,则使用默认值 100vw(全屏宽度)。
  • 其次,sizes 属性更改了自动生成的 srcset 值的行为。如果不存在 sizes 值,则会生成一个小的 srcset,适用于固定大小的图像(1x/2x/etc)。如果定义了 sizes,则会生成一个大的 srcset,适用于响应式图像(640w/750w/etc)。如果 sizes 属性包含诸如 50vw 之类的大小,这些大小表示视口宽度的百分比,则会修剪 srcset 以不包括任何太小而永远不需要的值。

例如,如果您知道您的样式将导致图像在移动设备上是全宽的,在平板电脑上的 2 列布局中,以及在桌面显示器上的 3 列布局中,则应包含如下所示的 sizes 属性

import Image from 'next/image'
 
export default function Page() {
  return (
    <div className="grid-element">
      <Image
        fill
        src="/example.png"
        sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
      />
    </div>
  )
}

此示例 sizes 可能会对性能指标产生显着影响。如果没有 33vw sizes,从服务器选择的图像将是其所需宽度的 3 倍。由于文件大小与宽度的平方成正比,因此如果没有 sizes,用户将下载比必要大小大 9 倍的图像。

了解有关 srcsetsizes 的更多信息

quality

quality={75} // {number 1-100}

优化图像的质量,一个介于 1100 之间的整数,其中 100 是最佳质量,因此文件大小最大。默认为 75

如果在 next.config.js 中定义了 qualities 配置,则 quality prop 必须与配置中定义的值之一匹配。

须知:如果原始源图像质量已经很低,则将 quality prop 设置得太高可能会导致生成的优化图像大于原始源图像。

priority

priority={false} // {false} | {true}

为 true 时,Next.js 将预加载图像。对于使用 priority 的图像,会自动禁用懒加载。如果 loading 属性也被使用并设置为 lazy,则 priority 属性不能使用。loading 属性仅用于高级用例。当需要 priority 时,请删除 loading

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

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

placeholder

placeholder = 'empty' // "empty" | "blur" | "data:image/..."

在图像加载时使用的占位符。可能的值为 bluremptydata:image/...。默认为 empty

当为 blur 时,blurDataURL 属性将用作占位符。如果 src 是来自静态导入的对象,并且导入的图像是 .jpg.png.webp.avif,则 blurDataURL 将自动填充,除非检测到图像是动画。

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

当为 data:image/... 时,数据 URL 将在图像加载时用作占位符。

当为 empty 时,图像加载时将没有占位符,只有空白空间。

试试看

高级 Props

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

style

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

components/ProfileImage.js
const imageStyle = {
  borderRadius: '50%',
  border: '1px solid #fff',
}
 
export default function ProfileImage() {
  return <Image src="..." style={imageStyle} />
}

请记住,所需的 widthheight 属性可能会与您的样式交互。如果您使用样式来修改图像的宽度,您还应该将其高度样式设置为 auto 以保持其固有的纵横比,否则您的图像将会失真。

onLoadingComplete

<Image onLoadingComplete={(img) => console.log(img.naturalWidth)} />

警告:自 Next.js 14 起已弃用,推荐使用 onLoad

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

回调函数将被调用,并带有一个参数,即底层 <img> 元素的引用。

onLoad

<Image onLoad={(e) => console.log(e.target.naturalWidth)} />

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

回调函数将被调用,并带有一个参数,即 Event 对象,该对象具有一个 target 属性,它引用了底层的 <img> 元素。

onError

<Image onError={(e) => console.error(e.target.id)} />

如果图像加载失败,将调用此回调函数。

loading

loading = 'lazy' // {lazy} | {eager}

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

当设置为 lazy 时,延迟加载图像,直到它到达距离视口一定距离的位置。

当设置为 eager 时,立即加载图像。

了解更多关于 loading 属性

blurDataURL

一个 Data URL,用作 src 图像成功加载之前的占位符图像。仅当与 placeholder="blur" 结合使用时才生效。

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

试试看

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

unoptimized

unoptimized = {false} // {false} | {true}

当为 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,
  },
}

overrideSrc

当向 <Image> 组件提供 src 属性时,将为生成的 <img> 自动生成 srcsetsrc 属性。

input.js
<Image src="/me.jpg" />
output.html
<img
  srcset="
    /_next/image?url=%2Fme.jpg&w=640&q=75 1x,
    /_next/image?url=%2Fme.jpg&w=828&q=75 2x
  "
  src="/_next/image?url=%2Fme.jpg&w=828&q=75"
/>

在某些情况下,可能不希望生成 src 属性,并且您可能希望使用 overrideSrc 属性覆盖它。

例如,当将现有网站从 <img> 升级到 <Image> 时,您可能希望为 SEO 目的(例如图像排名或避免重新抓取)保持相同的 src 属性。

input.js
<Image src="/me.jpg" overrideSrc="/override.jpg" />
output.html
<img
  srcset="
    /_next/image?url=%2Fme.jpg&w=640&q=75 1x,
    /_next/image?url=%2Fme.jpg&w=828&q=75 2x
  "
  src="/override.jpg"
/>

decoding

一个提示浏览器,指示是否应等待图像解码后再呈现其他内容更新。默认为 async

可能的值如下:

  • async - 异步解码图像,并允许在完成之前呈现其他内容。
  • sync - 同步解码图像,以便与其他内容原子性地呈现。
  • auto - 不偏好解码模式;浏览器决定最佳方式。

了解更多关于 decoding 属性

其他属性

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

配置选项

除了属性之外,您还可以在 next.config.js 中配置 Image 组件。以下选项可用:

localPatterns

您可以选择在 next.config.js 文件中配置 localPatterns,以允许优化特定路径并阻止所有其他路径。

next.config.js
module.exports = {
  images: {
    localPatterns: [
      {
        pathname: '/assets/images/**',
        search: '',
      },
    ],
  },
}

须知:上面的示例将确保 next/imagesrc 属性必须以 /assets/images/ 开头,并且不能带有查询字符串。尝试优化任何其他路径将响应 400 Bad Request。

remotePatterns

为了保护您的应用程序免受恶意用户的侵害,需要进行配置才能使用外部图像。这确保了只有来自您帐户的外部图像才能从 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/imagesrc 属性必须以 https://example.com/account123/ 开头,并且不能带有查询字符串。任何其他协议、主机名、端口或不匹配的路径都将响应 400 Bad Request。

以下是 next.config.js 文件中使用通配符模式的 remotePatterns 属性的示例:

next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: '**.example.com',
        port: '',
        search: '',
      },
    ],
  },
}

须知:上面的示例将确保 next/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/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'],
  },
}

loaderFile

如果您想使用云提供商来优化图像,而不是使用 Next.js 内置的 Image Optimization API,您可以在 next.config.js 中配置 loaderFile,如下所示:

next.config.js
module.exports = {
  images: {
    loader: 'custom',
    loaderFile: './my/image/loader.js',
  },
}

这必须指向相对于您的 Next.js 应用程序根目录的文件。该文件必须导出一个默认函数,该函数返回一个字符串,例如:

my/image/loader.js
export default function myImageLoader({ src, width, quality }) {
  return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}

或者,您可以使用 loader 属性 来配置 next/image 的每个实例。

示例

高级

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

deviceSizes

如果您知道用户的预期设备宽度,您可以使用 next.config.js 中的 deviceSizes 属性指定设备宽度断点列表。当 next/image 组件使用 sizes 属性时,将使用这些宽度来确保为用户的设备提供正确的图像。

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

next.config.js
module.exports = {
  images: {
    deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
  },
}

imageSizes

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

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

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

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

qualities

默认的 Image Optimization API 将自动允许 1 到 100 的所有质量值。如果您希望限制允许的质量值,您可以向 next.config.js 添加配置。

next.config.js
module.exports = {
  images: {
    qualities: [25, 50, 75],
  },
}

在上面的示例中,仅允许三个质量值:25、50 和 75。如果 quality 属性与此数组中的值不匹配,则图像将失败并返回 400 Bad Request。

formats

默认的 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%。这意味着首次请求图像时,通常会较慢,然后后续缓存的请求会更快。
  • 如果您使用代理/CDN 自托管在 Next.js 前端,则必须配置代理以转发 Accept 标头。

缓存行为

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

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

可以通过读取 x-nextjs-cache 响应标头的值来确定图像的缓存状态。可能的值如下:

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

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

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

minimumCacheTTL

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

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

优化图像的到期时间(或最大期限)由 minimumCacheTTL 或上游图像 Cache-Control 标头定义,以较大者为准。

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

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

disableStaticImages

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

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

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

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

dangerouslyAllowSVG

默认的 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',
  },
}

动画图像

默认的 loader 将自动绕过动画图像的 Image Optimization,并按原样提供图像。

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

响应式图像

默认生成的 srcset 包含 1x2x 图像,以支持不同的设备像素比。但是,您可能希望渲染一个可以随视口 растягиваться 的响应式图像。在这种情况下,您需要设置 sizes 以及 style(或 className)。

您可以使用以下方法之一来渲染响应式图像。

使用静态导入的响应式图像

如果源图像不是动态的,您可以静态导入以创建响应式图像

components/author.js
import Image from 'next/image'
import me from '../photos/me.jpg'
 
export default function Author() {
  return (
    <Image
      src={me}
      alt="Picture of the author"
      sizes="100vw"
      style={{
        width: '100%',
        height: 'auto',
      }}
    />
  )
}

试试看

具有宽高比的响应式图像

如果源图像是动态的或远程 URL,您还需要提供 widthheight 来设置响应式图像的正确宽高比

components/page.js
import Image from 'next/image'
 
export default function Page({ photoUrl }) {
  return (
    <Image
      src={photoUrl}
      alt="Picture of the author"
      sizes="100vw"
      style={{
        width: '100%',
        height: 'auto',
      }}
      width={500}
      height={300}
    />
  )
}

试试看

具有 fill 的响应式图像

如果您不知道宽高比,您需要设置 fill 属性,并在父元素上设置 position: relative。 可选地,您可以根据所需的拉伸或裁剪行为设置 object-fit 样式

app/page.js
import Image from 'next/image'
 
export default function Page({ photoUrl }) {
  return (
    <div style={{ position: 'relative', width: '300px', height: '500px' }}>
      <Image
        src={photoUrl}
        alt="Picture of the author"
        sizes="300px"
        fill
        style={{
          objectFit: 'contain',
        }}
      />
    </div>
  )
}

试试看

主题检测 CSS

如果您想为浅色和深色模式显示不同的图像,您可以创建一个新组件,该组件包裹两个 <Image> 组件,并根据 CSS 媒体查询显示正确的组件。

components/theme-image.module.css
.imgDark {
  display: none;
}
 
@media (prefers-color-scheme: dark) {
  .imgLight {
    display: none;
  }
  .imgDark {
    display: unset;
  }
}
components/theme-image.tsx
import styles from './theme-image.module.css'
import Image, { ImageProps } from 'next/image'
 
type Props = Omit<ImageProps, 'src' | 'priority' | 'loading'> & {
  srcLight: string
  srcDark: string
}
 
const ThemeImage = (props: Props) => {
  const { srcLight, srcDark, ...rest } = props
 
  return (
    <>
      <Image {...rest} src={srcLight} className={styles.imgLight} />
      <Image {...rest} src={srcDark} className={styles.imgDark} />
    </>
  )
}

须知loading="lazy" 的默认行为确保仅加载正确的图像。您不能使用 priorityloading="eager"`,因为这会导致加载两个图像。 相反,您可以使用 fetchPriority="high"

试试看

getImageProps

对于更高级的用例,您可以调用 getImageProps() 来获取将传递给底层 <img> 元素的 props,并将其传递给另一个组件、样式、画布等。

这也避免了调用 React useState(),因此可以带来更好的性能,但它不能与 placeholder 属性一起使用,因为占位符将永远不会被移除。

主题检测 Picture

如果您想为浅色和深色模式显示不同的图像,您可以使用 <picture> 元素,以根据用户的 首选颜色方案 显示不同的图像。

app/page.js
import { getImageProps } from 'next/image'
 
export default function Page() {
  const common = { alt: 'Theme Example', width: 800, height: 400 }
  const {
    props: { srcSet: dark },
  } = getImageProps({ ...common, src: '/dark.png' })
  const {
    props: { srcSet: light, ...rest },
  } = getImageProps({ ...common, src: '/light.png' })
 
  return (
    <picture>
      <source media="(prefers-color-scheme: dark)" srcSet={dark} />
      <source media="(prefers-color-scheme: light)" srcSet={light} />
      <img {...rest} />
    </picture>
  )
}

美术指导

如果您想为移动设备和桌面设备显示不同的图像(有时称为 美术指导),您可以为 getImageProps() 提供不同的 srcwidthheightquality 属性。

app/page.js
import { getImageProps } from 'next/image'
 
export default function Home() {
  const common = { alt: 'Art Direction Example', sizes: '100vw' }
  const {
    props: { srcSet: desktop },
  } = getImageProps({
    ...common,
    width: 1440,
    height: 875,
    quality: 80,
    src: '/desktop.jpg',
  })
  const {
    props: { srcSet: mobile, ...rest },
  } = getImageProps({
    ...common,
    width: 750,
    height: 1334,
    quality: 70,
    src: '/mobile.jpg',
  })
 
  return (
    <picture>
      <source media="(min-width: 1000px)" srcSet={desktop} />
      <source media="(min-width: 500px)" srcSet={mobile} />
      <img {...rest} style={{ width: '100%', height: 'auto' }} />
    </picture>
  )
}

背景 CSS

您甚至可以将 srcSet 字符串转换为 image-set() CSS 函数,以优化背景图像。

app/page.js
import { getImageProps } from 'next/image'
 
function getBackgroundImage(srcSet = '') {
  const imageSet = srcSet
    .split(', ')
    .map((str) => {
      const [url, dpi] = str.split(' ')
      return `url("${url}") ${dpi}`
    })
    .join(', ')
  return `image-set(${imageSet})`
}
 
export default function Home() {
  const {
    props: { srcSet },
  } = getImageProps({ alt: '', width: 128, height: 128, src: '/img.png' })
  const backgroundImage = getBackgroundImage(srcSet)
  const style = { height: '100vh', width: '100vw', backgroundImage }
 
  return (
    <main style={style}>
      <h1>Hello World</h1>
    </main>
  )
}

已知的浏览器 Bug

next/image 组件使用浏览器原生 懒加载,对于 Safari 15.4 之前的旧版本浏览器,可能会回退到 eager loading。 当使用 blur-up 占位符时,Safari 12 之前的旧版本浏览器将回退到空占位符。 当使用 width/heightauto 的样式时,可能会在 Safari 15 之前的旧版本浏览器上导致 布局偏移 (Layout Shift),因为这些浏览器不 保留宽高比。 有关更多详细信息,请参阅 此 MDN 视频

  • Safari 15 - 16.3 在加载时显示灰色边框。 Safari 16.4 修复了此问题。 可能的解决方案
    • 使用 CSS @supports (font: -apple-system-body) and (-webkit-appearance: none) { img[loading="lazy"] { clip-path: inset(0.6px) } }
    • 如果图像位于首屏上方,请使用 priority
  • Firefox 67+ 在加载时显示白色背景。 可能的解决方案

版本历史

版本变更
v15.0.0contentDispositionType 配置默认值更改为 attachment
v14.2.23添加了 qualities 配置。
v14.2.15添加了 decoding 属性,并添加了 localPatterns 配置。
v14.2.14添加了 remotePatterns.search 属性。
v14.2.0添加了 overrideSrc 属性。
v14.1.0getImageProps() 已稳定。
v14.0.0onLoadingComplete 属性和 domains 配置已弃用。
v13.4.14placeholder 属性支持 data:/image...
v13.2.0添加了 contentDispositionType 配置。
v13.0.6添加了 ref 属性。
v13.0.0next/image 导入已重命名为 next/legacy/imagenext/future/image 导入已重命名为 next/imagecodemod 可用于安全且自动地重命名您的导入。 移除了 <span> 包装器。 移除了 layoutobjectFitobjectPositionlazyBoundarylazyRoot 属性。 alt 是必需的。 onLoadingComplete 接收对 img 元素的引用。 移除了内置加载器配置。
v12.3.0remotePatternsunoptimized 配置已稳定。
v12.2.0添加了实验性的 remotePatterns 和实验性的 unoptimized 配置。 移除了 layout="raw"
v12.1.1添加了 style 属性。 添加了对 layout="raw" 的实验性支持。
v12.1.0添加了 dangerouslyAllowSVGcontentSecurityPolicy 配置。
v12.0.9添加了 lazyRoot 属性。
v12.0.0添加了 formats 配置。
添加了 AVIF 支持。
包装器 <div> 更改为 <span>
v11.1.0添加了 onLoadingCompletelazyBoundary 属性。
v11.0.0src 属性支持静态导入。
添加了 placeholder 属性。
添加了 blurDataURL 属性。
v10.0.5添加了 loader 属性。
v10.0.1添加了 layout 属性。
v10.0.0引入了 next/image