本文将介绍如何在 Next.js 中使用 <Image />
组件,以及为什么需要该组件来集成响应式和优化的图像。首先探讨 <Image />
组件的主要功能,然后,将探讨 <Image />
组件如何在后台执行优化,以及进一步优化图像的其他方法。
如何使用 <Image />
组件
首先分析这个基本的 <Image />
组件:
javascript
// 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
组件还可以接受src
的Image
对象,而不是图像的字符串路径。基于这个警告,可以将上面的代码更改如下:
javascript
import Image from 'next/image'
import ImageToRender from 'public/profile.png'
export default function Page() {
// 渲染图像对象
return (
<Image
src={ImageToRender}
alt="Picture of the author"
/>
)
}
请注意不再指定 width
和 height
属性。以这种方式渲染图像允许 Next.js 推断图像的尺寸,而无需提供宽度和高度属性,从而减少累积布局偏移(CLS)。累积布局转变 (CLS)是一种量化用户在与网页交互时遇到意外布局转变的频率的方法。动态图像调整大小是导致这一数字上升的主要原因,因此这对网站性能和用户体验不利。这就是为什么在使用字符串路径渲染图像时如果不提供 width
和 height
,Next.js 会抛出错误。
现在来看看如何渲染来自外部源的图像,可能会想直接将图像的 URL 输入到 Image
组件中,如下所示:
javascript
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
以允许来自特定来源的图像:
java
// 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: '/**'
}
注意:指定
avif
和webp
格式会自动将任何png
或jpg
图像转换为所需的格式。
背景图片怎么样?要创建简单的背景图像,需要在 <Image />
组件中使用以下属性:
javascript
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',
}}
/>
)
}
来一一分解 fill
、sizes
、objectFit
的作用:
fill
:使用fill
,不需要指定width
和height
属性,而是图像将fill
父元素的整个宽度和高度,而父元素最终是负责渲染页面的元素。sizes
:sizes
属性通常与fill
属性结合使用,允许指定图像应占用的视口宽度的百分比。因此,如果指定50vw
,则意味着srcset
(或图像数量)将被修剪,以不包含任何太小而不必要的值。可以在下面的 Next.js 官方文档中找到解释尺寸用例的一个很好的示例【点击查看示例】。objectFit
:是一种 CSS 样式,它定义了图像如何适合屏幕。三个可用选项是cover
、contain
和none
;尝试使用这些选项,看看哪一个可以提供最清晰的背景图像来满足需求。
<Image />
如何优化图像
在底层,Next.js 使用 sharp
作为依赖项,这是一个高速 node 模块,可以使图像得到优化并且 web-friendly
。包括通过将图像从 png
和 jpg
转换为轻量级格式(例如 webp
和 avif
)来减小文件大小。
此外,在 Next.js 优化图像后,它们将在 _next/image
路由上提供。例如:example.com/_next/image/profile.png
。这反过来又会带来额外的性能提升。
最后,Image
组件可以使用两个额外的属性,即 priority
和 quality
,来进一步优化图像:
priority
:priority
属性是一个布尔值,允许指定何时渲染图像。如果将优先级设置为true
,则图像将在渲染 Web 内容之前加载,这可以消除潜在的闪烁。quality
:是一个介于1--100
之间的数值,用于确定图像的清晰度。默认值为75
,因此为了获得最清晰的图像,应将其设置为100
。但请记住,该值越高,图像的文件大小就越大,这可能会在渲染大量图像时导致性能问题。