likes
comments
collection
share

Next.js 14 中通过优化图像增强用户体验

作者站长头像
站长
· 阅读数 4

Next.js 14 中通过优化图像增强用户体验

本文将介绍如何在 Next.js 中使用 <Image /> 组件,以及为什么需要该组件来集成响应式和优化的图像。首先探讨 <Image /> 组件的主要功能,然后,将探讨 <Image /> 组件如何在后台执行优化,以及进一步优化图像的其他方法。

如何使用 <Image /> 组件

首先分析这个基本的 <Image /> 组件:

// https://nextjs.org/docs/app/api-reference/components/image

import Image from 'next/image'
 
export default function Page() {
  // 对于存储在 public/ 文件夹中的图像。
  return (
    <Image
      src="/profile.png"
      width={500}
      height={500}
      alt="Picture of the author"
    />
  )
}

这里 src 的使用方式与标准 <img /> 组件类似,但有一个警告:

Image 组件还可以接受 srcImage 对象,而不是图像的字符串路径。基于这个警告,可以将上面的代码更改如下:

import Image from 'next/image'
import ImageToRender from 'public/profile.png'
 
export default function Page() {
  // 渲染图像对象
  return (
    <Image
      src={ImageToRender}
      alt="Picture of the author"
    />
  )
}

请注意不再指定 widthheight 属性。以这种方式渲染图像允许 Next.js 推断图像的尺寸,而无需提供宽度和高度属性,从而减少累积布局偏移(CLS)。累积布局转变 (CLS)是一种量化用户在与网页交互时遇到意外布局转变的频率的方法。动态图像调整大小是导致这一数字上升的主要原因,因此这对网站性能和用户体验不利。这就是为什么在使用字符串路径渲染图像时如果不提供 widthheight,Next.js 会抛出错误。

现在来看看如何渲染来自外部源的图像,可能会想直接将图像的 URL 输入到 Image 组件中,如下所示:

import Image from 'next/image'
 
export default function Page() {
  return (
    <Image
      src="https://www.example.com/image.png"
      width={500}
      height={500}
      alt="Picture of the author"
    />
  )
}

如果这样做,Next.js 将抛出错误。这是因为需要首先将要使用 Next.js 服务器优化图像的域列入白名单。为此,请打开 next.config.js 文件并添加 remotePatterns 以允许来自特定来源的图像:

// next.config.js

module.exports = {
  images: {
    // Used to support only these image formats, these image
    // formats are smaller in file size compared to .png and .jpg
    // files.
    formats: ['image/avif', 'image/webp'],
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'www.example.com',
        // optional, specify this if needed
        port: '',
        // optional, specify this for more control over
        // which images to optimize.
        pathname: '/**'
}

注意:指定 avifwebp 格式会自动将任何 pngjpg 图像转换为所需的格式。

背景图片怎么样?要创建简单的背景图像,需要在 <Image /> 组件中使用以下属性:

import Image from 'next/image'
 
export default function Page() {
  return (
    <Image
      src="/profile.png"
      alt="Picture of the author"
      fill
      sizes="100vw"
      style={{
         objectFit: 'cover',
      }}
    />
  )
}

来一一分解 fillsizesobjectFit 的作用:

  • fill:使用 fill,不需要指定 widthheight 属性,而是图像将 fill 父元素的整个宽度和高度,而父元素最终是负责渲染页面的元素。
  • sizessizes 属性通常与 fill 属性结合使用,允许指定图像应占用的视口宽度的百分比。因此,如果指定 50vw,则意味着 srcset(或图像数量)将被修剪,以不包含任何太小而不必要的值。可以在下面的 Next.js 官方文档中找到解释尺寸用例的一个很好的示例【点击查看示例】。
  • objectFit:是一种 CSS 样式,它定义了图像如何适合屏幕。三个可用选项是 covercontainnone;尝试使用这些选项,看看哪一个可以提供最清晰的背景图像来满足需求。

<Image /> 如何优化图像

在底层,Next.js 使用 sharp 作为依赖项,这是一个高速 node 模块,可以使图像得到优化并且 web-friendly。包括通过将图像从 pngjpg 转换为轻量级格式(例如 webpavif)来减小文件大小。

此外,在 Next.js 优化图像后,它们将在 _next/image 路由上提供。例如:example.com/_next/image/profile.png。这反过来又会带来额外的性能提升。

最后,Image 组件可以使用两个额外的属性,即 priorityquality,来进一步优化图像:

  • prioritypriority属性是一个布尔值,允许指定何时渲染图像。如果将优先级设置为 true,则图像将在渲染 Web 内容之前加载,这可以消除潜在的闪烁。
  • quality:是一个介于 1–100 之间的数值,用于确定图像的清晰度。默认值为 75,因此为了获得最清晰的图像,应将其设置为 100。但请记住,该值越高,图像的文件大小就越大,这可能会在渲染大量图像时导致性能问题。