跳至内容

图片优化

示例

根据 Web Almanac,图片占据了典型网站 页面权重 的很大一部分,并且会对您网站的 LCP 性能 产生相当大的影响。

Next.js Image 组件扩展了 HTML <img> 元素,并具有自动图片优化功能

  • 大小优化:使用 WebP 和 AVIF 等现代图片格式,自动为每个设备提供正确大小的图片。
  • 视觉稳定性:在加载图片时,自动防止 布局偏移
  • 更快的页面加载速度:图片仅在进入视口时使用原生浏览器延迟加载加载,并提供可选的模糊加载占位符。
  • 资产灵活性:即使对于存储在远程服务器上的图片,也可以按需调整图片大小。

🎥观看:详细了解如何使用 next/imageYouTube (9 分钟)

用法

import Image from 'next/image'

然后,您可以为图片定义 src(本地或远程)。

本地图片

要使用本地图片,请 import 您的 .jpg.png.webp 图片文件。

Next.js 将 自动确定图片的内在 widthheight,这基于导入的文件。这些值用于确定图片比例并防止在加载图片时出现 累积布局偏移

app/page.js
import Image from 'next/image'
import profilePic from './me.png'
 
export default function Page() {
  return (
    <Image
      src={profilePic}
      alt="Picture of the author"
      // width={500} automatically provided
      // height={500} automatically provided
      // blurDataURL="data:..." automatically provided
      // placeholder="blur" // Optional blur-up while loading
    />
  )
}

警告:不支持动态 await import()require()import 必须是静态的,以便可以在构建时进行分析。

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

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

远程图片

要使用远程图片,src 属性应为 URL 字符串。

由于 Next.js 在构建过程中无法访问远程文件,因此您需要手动提供 widthheight 和可选的 blurDataURL 属性。

widthheight 属性用于推断图像的正确纵横比,并避免图像加载时出现的布局偏移。widthheight 不会 确定渲染的图像文件大小。详细了解 图像大小调整

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

为了安全地允许优化图像,请在 next.config.js 中定义受支持的 URL 模式列表。请尽可能具体,以防止恶意使用。例如,以下配置仅允许来自特定 AWS S3 存储桶的图像

next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 's3.amazonaws.com',
        port: '',
        pathname: '/my-bucket/**',
      },
    ],
  },
}

详细了解 remotePatterns 配置。如果要对图像 src 使用相对 URL,请使用 loader

域名

有时您可能希望优化远程图像,但仍使用内置的 Next.js 图像优化 API。为此,请将 loader 保留为其默认设置,并为 Image src 属性输入绝对 URL。

为了保护您的应用程序免受恶意用户的攻击,您必须定义一个远程主机名列表,这些主机名您打算与 next/image 组件一起使用。

详细了解 remotePatterns 配置。

加载器

请注意,在 前面的示例 中,为本地图像提供了部分 URL("/me.png")。这是因为加载器架构。

加载器是一个生成图像 URL 的函数。它修改提供的 src,并生成多个 URL 以请求不同大小的图像。这些多个 URL 用于自动 srcset 生成,以便访问您网站的访问者将获得适合其视口大小的图像。

Next.js 应用程序的默认加载器使用内置的图像优化 API,该 API 优化来自网络任何位置的图像,然后直接从 Next.js Web 服务器提供这些图像。如果您希望直接从 CDN 或图像服务器提供图像,可以使用几行 JavaScript 编写自己的加载器函数。

您可以使用 loader 属性 为每个图像定义加载器,或者使用 loaderFile 配置 在应用程序级别定义加载器。

优先级

您应该将 priority 属性添加到将成为每个页面 最大内容绘制 (LCP) 元素 的图像。这样做可以让 Next.js 特别优先加载图像(例如,通过预加载标签或优先级提示),从而显著提高 LCP。

LCP 元素通常是页面视口中可见的最大图像或文本块。当您运行 next dev 时,如果 LCP 元素是缺少 priority 属性的 <Image>,您将看到控制台警告。

确定 LCP 图像后,您可以像这样添加属性

app/page.js
import Image from 'next/image'
import profilePic from '../public/me.png'
 
export default function Page() {
  return <Image src={profilePic} alt="Picture of the author" priority />
}

查看 next/image 组件文档 中有关优先级的更多信息。

图像大小调整

图像影响性能的最常见方式之一是布局偏移,即图像在加载时将页面上的其他元素推开。此性能问题对用户来说非常恼人,因此它有自己的核心 Web 指标,称为 累积布局偏移。避免基于图像的布局偏移的方法是 始终调整图像大小。这允许浏览器在图像加载之前为图像保留足够的空间。

因为 next/image 旨在保证良好的性能结果,所以它不能以可能导致布局偏移的方式使用,并且**必须**以以下三种方式之一进行大小调整

  1. 自动使用 静态导入
  2. 手动包含 widthheight 属性,用于确定图像的纵横比。
  3. 隐式使用 fill,这会导致图像扩展以填充其父元素。

如果我不知道图像的大小怎么办?

如果您从不知道图像大小的源访问图像,您可以执行以下操作

使用 fill

fill 属性允许图像的大小由其父元素决定。考虑使用 CSS 为图像的父元素在页面上提供空间,以及 sizes 属性以匹配任何媒体查询断点。您还可以使用 object-fitfillcontaincover 以及 object-position 来定义图像应该如何占据该空间。

规范化您的图像

如果您从受您控制的源提供图像,请考虑修改您的图像管道以将图像规范化为特定大小。

修改您的 API 调用

如果您的应用程序使用 API 调用(例如到 CMS)检索图像 URL,则您可能能够修改 API 调用以连同 URL 一起返回图像尺寸。

如果上述方法均不适用于调整图像大小,则 next/image 组件旨在与标准 <img> 元素一起在页面上良好运行。

样式

Image 组件的样式设置类似于普通 <img> 元素的样式设置,但需要注意一些准则

  • 使用 classNamestyle,而不是 styled-jsx
    • 在大多数情况下,我们建议使用 className 属性。这可以是导入的 CSS 模块全局样式表 等。
    • 您还可以使用 style 属性分配内联样式。
    • 您不能使用 styled-jsx,因为它作用域限定到当前组件(除非您将样式标记为 global)。
  • 使用 fill 时,父元素必须具有 position: relative
    • 这对于在该布局模式下正确渲染图像元素是必要的。
  • 使用 fill 时,父元素必须具有 display: block
    • 这是 <div> 元素的默认值,但在其他情况下应指定。

示例

响应式

Responsive image filling the width and height of its parent container
import Image from 'next/image'
import mountains from '../public/mountains.jpg'
 
export default function Responsive() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column' }}>
      <Image
        alt="Mountains"
        // Importing an image will
        // automatically set the width and height
        src={mountains}
        sizes="100vw"
        // Make the image display full width
        style={{
          width: '100%',
          height: 'auto',
        }}
      />
    </div>
  )
}

填充容器

Grid of images filling parent container width
import Image from 'next/image'
import mountains from '../public/mountains.jpg'
 
export default function Fill() {
  return (
    <div
      style={{
        display: 'grid',
        gridGap: '8px',
        gridTemplateColumns: 'repeat(auto-fit, minmax(400px, auto))',
      }}
    >
      <div style={{ position: 'relative', height: '400px' }}>
        <Image
          alt="Mountains"
          src={mountains}
          fill
          sizes="(min-width: 808px) 50vw, 100vw"
          style={{
            objectFit: 'cover', // cover, contain, none
          }}
        />
      </div>
      {/* And more images in the grid... */}
    </div>
  )
}

背景图片

Background image taking full width and height of page
import Image from 'next/image'
import mountains from '../public/mountains.jpg'
 
export default function Background() {
  return (
    <Image
      alt="Mountains"
      src={mountains}
      placeholder="blur"
      quality={100}
      fill
      sizes="100vw"
      style={{
        objectFit: 'cover',
      }}
    />
  )
}

有关 Image 组件与各种样式结合使用的示例,请参阅Image 组件演示

其他属性

查看 next/image 组件可用的所有属性。

配置

可以在 next.config.js 文件 中配置 next/image 组件和 Next.js 图片优化 API。这些配置允许您启用远程图片定义自定义图片断点更改缓存行为 等。

阅读完整的图片配置文档以获取更多信息。