Image 组件和图片优化

示例

10.0.0 版本开始,Next.js 内置了图片组件和自动图片优化功能。

Next.js 的 Image 组件(即 next/image)是对 HTML 的 <img> 元素的扩展,跟进了最新的 web 技术。

自动图片优化功能(Automatic Image Optimization)能够调整图片尺寸、优化图片并以最新的 WebP 格式传输图片(如果浏览器支持 WebP 格式的话)。这样就可以避免将较大的图片传送到视口(viewport)较小的设备上。此功能还允许 Next.js 自动采用未来的图片格式,并将其传输给支持这些格式的浏览器。

自动图片优化功能可以支持任何图片来源。即使是托管在外部数据源上(例如,CMS),仍可对图片进行优化。

Next.js 无需在构建时优化图片,而是根据用户的请求按需优化图片。与静态站点生成器和纯静态解决方案不同,无论发布 10 张还是 1000 万张图片,构建时间都不会增加。

图片默认是延迟加载的。这意味着你的页面不会因为加载视口(viewport)外的图片而影响页面的加载速度。当图片进入视口(viewport)时才加载。

始终以这种方式渲染图片是为了避免 累计布局偏移(Cumulative Layout Shift),此 Core Web Vital 被 Google 作为参数用于 搜索排名

图片组件

要在应用中添加图片的话,首先导入(import)next/image 组件:

import Image from 'next/image'

function Home() {
  return (
    <>
      <h1>My Homepage</h1>
      <Image
        src="/me.png"
        alt="Picture of the author"
        width={500}
        height={500}
      />
      <p>Welcome to my homepage!</p>
    </>
  )
}

export default Home

Image Imports

You can import images that live in your project. (Note that require is not supported—only import.)

With direct imports, width, height, and blurDataURL will be automatically provided to the image component. Alt text is still needed separately.

import Image from 'next/image'
import profilePic from '../public/me.png'

function Home() {
  return (
    <>
      <h1>My Homepage</h1>
      <Image
        src={profilePic}
        alt="Picture of the author"
        // width={500} automatically provided
        // height={500} automatically provided
        // blurDataURL="data:..." automatically provided
        // Optionally allows to add a blurred version of the image while loading
        // placeholder="blur"
      />
      <p>Welcome to my homepage!</p>
    </>
  )
}

For dynamic or remote images, you'll have to provide width, height and blurDataURL manually.

Properties

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

配置

除了使用 next/image 组件的 属性 外,你还可以通过 next.config.js 来针对图片优化功能配置更高级的用法。

域名

要为外部网站上托管的图片启用图片优化功能,请先将图片的 src 地址设置完整的网址(即,带域名的地址),然后指定哪些 域名 需要开启优化功能。这是为了确保不会误伤其它外部网址。当 loader 被设置为外部图片服务时,此选项将被忽略。

module.exports = {
  images: {
    domains: ['example.com'],
  },
}

Loader

如果希望使用第三方云服务来优化图片,而不是 Next.js 的内置图片优化功能时,则需要配置 loader 和路径前缀参数。这让你可以为图片设置相对路径的 src,并自动为你所选择的云服务生成正确的完整网址。

module.exports = {
  images: {
    loader: 'imgix',
    path: 'https://example.com/myaccount/',
  },
}

目前支持以下云服务提供商:

  • Vercel: Works automatically when you deploy on Vercel, no configuration necessary. Learn more
  • Imgix: loader: 'imgix'
  • Cloudinary: loader: 'cloudinary'
  • Akamai: loader: 'akamai'
  • Default: Works automatically with next dev, next start, or a custom server

如果你需要支持其它云服务提供商,你可以为 next/image 设置 loader 属性。

当使用 next export 时,不支持 next/image 组件的默认加载器(loader)。但是,其它加载器(loaders)时可以使用的。

缓存

下面介绍默认 loader 的缓存算法。对于所有其它的 loader,请参考响应的云服务提供商的文档。

图片根据用户的请求进行动态优化,并存储到 <distDir>/cache/images 目录下。优化过的图片文件将用于后续的请求,直到过期为止。当用户请求一个已经过期的图片文件时,将首先删除先前缓存的文件,然后生成新的经过优化的文件。

过期时间(或者最长寿命)由上游服务器的 Cache-Control 标头确定。

如果在 Cache-Control 中找到 s-maxage,则使用 s-maxage。如果没有找到 s-maxage,则使用 max-age。如果没有找到 max-age,则设置为 60 秒。

你可以设置 deviceSizesimageSizes 来减少可能生成的图片总数。

高级设置

以下是高级设置示例,通常不需要。如果你选择设置以下属性,则将来 Next.js 更新时会覆盖 Next.js 的默认值。

设备尺寸

在某些情况下,如果你预先知到网站用户的设备宽度,则可以通过 deviceSizes 属性指定设备宽度的列表。当 next/image 组件设置了 layout="responsive"layout="fill" 时将使用这个宽度列表,在某个设备访问你的网站时,将向该设备传输列表中列出的图片尺寸。

如果不自定义配置,则使用如下的默认值。

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

图片尺寸

你可以通过 imageSizes 属性来指定图片宽度列表。这些宽度应该不同于(通常是小于) deviceSizes 属性中设置的宽度值,因为这两个属性值所对应的数组将被合并。当 next/image 组件设置了 layout="fixed"layout="intrinsic" 时,将使用这些宽度值。

如果不自定义配置,则使用如下的默认值。

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

Disable Static Imports

The default behavior allows you to import static files such as import icon from './icon.png and then pass that to the src property.

In some cases, you may wish to disable this feature if it conflicts with other plugins that expect the import to behave differently.

You can disable static image imports with the following configuration below.

module.exports = {
  images: {
    disableStaticImages: true,
  },
}

相关内容

以下是我们建议接下来需要学习的内容: