跳到内容

图片优化

示例

根据 Web Almanac,图片在典型网站的 页面权重 中占据了很大一部分,并且可能对你网站的 LCP 性能 产生显著影响。

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

  • 尺寸优化: 自动为每个设备提供正确尺寸的图片,使用现代图片格式如 WebP。
  • 视觉稳定性: 在图片加载时自动防止布局偏移
  • 更快的页面加载: 图片仅在进入视口时才使用原生浏览器懒加载进行加载,并带有可选的模糊占位符。
  • 资源灵活性: 按需调整图片大小,即使是存储在远程服务器上的图片

🎥 观看: 了解更多关于如何使用 next/imageYouTube (9 分钟)

用法

import Image from 'next/image'

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

本地图片

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

Next.js 将自动确定你导入的图片的固有 widthheight。这些值用于确定图片比例并防止 累积布局偏移,当你的图片正在加载时。

pages/index.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"
      // 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/**',
        search: '',
      },
    ],
  },
}

了解更多关于 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 元素是 <Image> 且没有 priority 属性,你将看到控制台警告。

一旦你确定了 LCP 图片,你可以像这样添加属性

app/page.js
import Image from 'next/image'
 
export default function Home() {
  return (
    <>
      <h1>My Homepage</h1>
      <Image
        src="/me.png"
        alt="Picture of the author"
        width={500}
        height={500}
        priority
      />
      <p>Welcome to my homepage!</p>
    </>
  )
}

查看 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/image 组件和 Next.js 图片优化 API 可以在 next.config.js 文件中配置。这些配置允许你启用远程图片定义自定义图片断点更改缓存行为等等。

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