Menu

<Image>

示例

这个 API 参考将帮助你理解如何使用 Image 组件可用的 属性配置选项。有关功能和用法,请参阅 Image 组件 页面。

app/page.js
import Image from "next/image";
 
export default function Page() {
  return (
    <Image
      src="/profile.png"
      width={500}
      height={500}
      alt="作者的照片"
    />
  );
}

属性

以下是 Image 组件可用的属性概述:

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

必需属性

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="作者的照片"
      />
    </div>
  );
}

src

必须是以下之一:

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

当使用外部 URL 时,你必须在 next.config.js 中将其添加到 remotePatterns

width

width 属性表示图像的 本质 宽度,单位为像素。

除了 静态导入的图像 或使用 fill 属性 的图像外,其他情况下都是必需的。

height

height 属性表示图像的 本质 高度,单位为像素。

除了 静态导入的图像 或使用 fill 属性 的图像外,其他情况下都是必需的。

值得注意的是

  • widthheight 属性结合使用,用于确定图像的宽高比,浏览器在图像加载之前会用这个比例来预留空间。
  • 本质尺寸并不总是意味着在浏览器中的渲染尺寸,实际渲染尺寸将由父容器决定。例如,如果父容器小于本质尺寸,图像将被缩小以适应容器。
  • 当宽度和高度未知时,你可以使用 fill 属性。

alt

alt 属性用于为屏幕阅读器和搜索引擎描述图像。它也是图像被禁用或加载过程中发生错误时的备用文本。

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

如果图像是 纯装饰性的不是为用户准备的alt 属性应该是一个空字符串 (alt="")。

了解更多

可选属性

除了必需的属性外,<Image /> 组件还接受一些额外的属性。本节描述了 Image 组件最常用的属性。在 高级属性 部分可以找到有关更少使用的属性的详细信息。

loader

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

loader 是一个返回图像 URL 字符串的函数,它接收以下参数:

以下是使用自定义 loader 的示例:

"use client";
 
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="作者的照片"
      width={500}
      height={500}
    />
  );
}

值得注意的是: 使用像 loader 这样接受函数的属性需要使用 客户端组件 来序列化提供的函数。

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

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/等)。如果定义了 sizes,会生成一个大的 srcset,适用于响应式图像 (640w/750w/等)。如果 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}

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

priority

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

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

你应该对任何检测到的 最大内容绘制 (LCP) 元素的图像使用 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 时,图像加载时将没有占位符,只有空白空间。

试试看:

高级属性

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

style

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

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

请记住,必需的宽度和高度属性可能会与你的样式交互。如果你使用样式来修改图像的宽度,你还应该将其高度样式设置为 auto,以保持其固有的宽高比,否则你的图像会被扭曲。

onLoadingComplete

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

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

一个回调函数,在图像完全加载并且 占位符 已被移除时调用。

回调函数将被调用,参数是对底层 <img> 元素的引用。

值得注意的是: 使用像 onLoadingComplete 这样接受函数的属性需要使用 客户端组件 来序列化提供的函数。

onLoad

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

一个回调函数,在图像完全加载并且 占位符 已被移除时调用。

回调函数将被调用,参数是一个 Event,其 target 引用底层 <img> 元素。

值得注意的是: 使用像 onLoad 这样接受函数的属性需要使用 客户端组件 来序列化提供的函数。

onError

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

一个回调函数,在图像加载失败时调用。

值得注意的是: 使用像 onError 这样接受函数的属性需要使用 客户端组件 来序列化提供的函数。

loading

建议: 这个属性仅用于高级用例。将图像切换为 eager 加载通常会损害性能。我们建议使用 priority 属性,它会急切地预加载图像。

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

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

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

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

了解更多关于 loading 属性

blurDataURL

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

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

试试看:

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

unoptimized

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

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

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"
/>

其他属性

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

  • srcSet。请改用 Device Sizes
  • decoding。它始终为 "async"

配置选项

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

remotePatterns

为了保护你的应用免受恶意用户的攻击,使用外部图像时需要进行配置。这确保只有你账户的外部图像可以通过 Next.js 图像优化 API 提供服务。这些外部图像可以在 next.config.js 文件中使用 remotePatterns 属性进行配置,如下所示:

next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "example.com",
        port: "",
        pathname: "/account123/**",
      },
    ],
  },
};

值得注意的是: 上面的示例将确保 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: "",
      },
    ],
  },
};

值得注意的是: 上面的示例将确保 next/imagesrc 属性必须以 https://img1.example.comhttps://me.avatar.example.com 或任意数量的子域名开头。任何其他协议、端口或不匹配的主机名都将响应 400 Bad Request。

pathnamehostname 都可以使用通配符模式,语法如下:

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

** 语法不能在模式中间使用。

值得注意的是: 当省略 protocolportpathname 时,默认使用通配符 **。不建议这样做,因为它可能允许恶意用户优化你不希望的 URL。

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 内置的图像优化 API,你可以在 next.config.js 中配置 loaderFile,如下所示:

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

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

my/image/loader.js
"use client";
 
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],
  },
};

formats

默认的 图像优化 API 将通过请求的 Accept 头自动检测浏览器支持的图像格式。

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

如果没有提供配置,将使用以下默认值。

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

你可以使用以下配置启用 AVIF 支持。

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

值得注意的是:

  • AVIF 通常需要多 20% 的时间进行编码,但比 WebP 压缩小 20%。这意味着第一次请求图像时通常会较慢,然后后续缓存的请求会更快。
  • 如果你在 Next.js 前面自托管代理/CDN,必须配置代理以转发 Accept 头。

缓存行为

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

图像会根据请求动态优化,并存储在 <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-Controlimmutable 永久缓存图像。

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

默认 加载器 出于以下原因不优化 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 时特别重要。

你可以选择配置 inline 以允许浏览器在直接访问时渲染图像,而不是下载它。

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

动画图像

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

对动画文件的自动检测是尽力而为的,支持 GIF、APNG 和 WebP。如果你想明确绕过给定动画图像的图像优化,请使用 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="作者的照片"
      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="作者的照片"
      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="作者的照片"
        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} />
    </>
  );
};
components/theme-image.js
import styles from "./theme-image.module.css";
import Image from "next/image";
 
const ThemeImage = (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> 元素的属性,然后将它们传递给另一个组件、样式、canvas 等。

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

主题检测 Picture

如果你想根据用户的 首选配色方案 显示不同的图像,你可以使用 <picture> 元素。

app/page.js
import { getImageProps } from "next/image";
 
export default function Page() {
  const common = { alt: "主题示例", 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: "艺术指导示例", 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>
  );
}

已知浏览器问题

这个 next/image 组件使用浏览器原生的 懒加载,对于 Safari 15.4 之前的旧浏览器可能会回退到急切加载。当使用模糊上升占位符时,Safari 12 之前的旧浏览器将回退到空占位符。当使用 width/heightauto 的样式时,可能会在 Safari 15 之前的旧浏览器上导致 布局偏移,这些浏览器不 保留宽高比。有关更多详细信息,请参阅 这个 MDN 视频

版本历史

版本变更
v15.0.0contentDispositionType 配置默认值改为 attachment
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/image。提供 codemod 以安全自动重命名导入。移除 <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