图像优化
根据Web Almanac的数据,图像占据了典型网站页面权重的很大一部分,并且对网站的LCP性能有相当大的影响。
Next.js的Image组件通过扩展HTML <img> 元素,提供了自动图像优化的功能:
-
尺寸优化: 为每个设备自动提供正确尺寸的图像,使用现代图像格式如WebP和AVIF。
-
视觉稳定性: 在图像加载时自动防止布局移位。
-
更快的页面加载: 使用原生浏览器懒加载,仅在图像进入视口时加载,可选择使用模糊占位符。
-
资产灵活性: 需要时对图像进行按需调整大小,即使是存储在远程服务器上的图像。
🎥 观看:学习如何使用next/image → YouTube (9分钟)。
使用
import Image from 'next/image'
然后,您可以为图像定义src(可以是本地或远程)。
本地图像
要使用本地图像,请import您的 .jpg、.png 或 .webp 图像文件。
Next.js 将根据导入的文件自动确定图像的width和height。这些值用于在图像加载时防止累积布局移位。
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} 会自动提供
// height={500} 会自动提供
// blurDataURL="data:..." 会自动提供
// placeholder="blur" // 可选,加载时的模糊占位符
/>
)
}
不支持动态的 await import() 或 require()。导入必须是静态的,以便在构建时进行分析。
远程图像
要使用远程图像,src 属性应该是一个 URL 字符串。
由于 Next.js 在构建过程中无法访问远程文件,您需要手动提供 width、height 和可选的 blurDataURL 属性。
width和height属性用于推断图像的正确纵横比,并避免加载图像时发生布局偏移。
宽度和高度并不决定图像文件的渲染大小。
了解有关图像大小
调整的更多信息。
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 存储桶的图像:
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 优化来自 Web 任何位置的图像, 然后直接从 Next.js Web 服务器提供它们。如果您想直接从 CDN 或图像服务器提供图像, 可以使用几行 JavaScript 编写自己的加载程序函数。
您可以使用 loader 属性
为每个图像定义一个加载程序,
或者使用 loaderFile 配置
在应用程序级别定义加载程序。
优先级
您应该为每个页面的 Largest Contentful Paint(LCP)元素添加priority 属性。
这样做允许 Next.js 为该图像加载设置特殊的优先级(例如通过 preload 标签或优先提示),从而提高 LCP。
LCP 元素通常是页面视口内可见的最大图像或文本块。
运行 next dev 时,如果 LCP 元素是一个没有 priority 属性的 <Image>,您将看到控制台警告。
一旦您确定了 LCP 图像,可以像这样添加属性:
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 组件文档中查看有关 priority 的更多信息。
图像大小
图像最常导致性能问题的方式之一是布局移位,即图像在 加载时将页面上的其他元素推动到周围。 这种性能问题对用户来说非常恼人,因此它有自己的核心Web Vitals,称为Cumulative Layout Shift(CLS)。 避免基于图像的布局移位的方法是始终调整图像的大小。这允许浏览器在加载之前准确地保留足够的空间。
由于 next/image 旨在确保良好的性能结果,因此不能以导致布局移位的方式使用它,并且必须以以下三种方式之一调整大小:
- 自动,使用静态导入
- 显式,通过包含
width和height属性 - 隐式,通过使用
fill,使图像扩展以填充其父元素。
如果我不知道我的图像大小怎么办?
如果您从不知道图像大小的源访问图像,有几件事情可以做:
使用 fill:
fill 属性允许图像按其父元素的大小进行调整。
考虑使用CSS为图像的父元素提供页面上的空间,并使用 sizes 属性来匹配任何媒体查询断点。
您还可以使用 fill、contain 或 cover 以及 object-position 来定义图像应该如何占用该空间。