渐进式图像加载的原理可以看这篇文章:渐进式图像加载
但 NextJS
的 Image
组件帮开发者内置了渐近加载的处理,需要在特定条件下使用
官网原话
Faster Page Loads: Images are only loaded when they enter the viewport using native browser lazy loading, with optional blur-up placeholders
.
更快的页面加载:只有当图像进入视口时,才会使用浏览器的原生懒加载进行加载,还可以选择使用模糊占位符
。
使用方式(静态引入)
import Image from "next/image";
import mountains from "/public/mountains.jpg";
const PlaceholderBlur = () => (
<Image
alt="Mountains"
src={mountains}
placeholder="blur"
width={700}
height={475}
/>
);
export default PlaceholderBlur;
placeholder="blur"
即可,但必须使用 Import
静态引入图片的方式,这样 `NextJS 在构建时才会分析并对图像做渐进式加载的预处理
使用方式(动态)
动态图像也即 src
类型是 string
时,placeholder=‘blur’
的 同时还必须给定 blurDataURL
,此参数可以给一个已知的模糊且比较小的图片,也可以直接给纯色背景。
业界通常会利用 webp
格式制作模糊缩略图作为预加载图像进行占位,或是提取图像重点颜色作为纯色背景进行占位。
我们这里的 DEMO
简单些,使用固定纯色进行占位。
import Image from "next/image";
import { rgbDataURL } from '@/tools'
const Color = () => (
<Image
alt="Dog"
src="/dog.jpg"
placeholder="blur"
blurDataURL={rgbDataURL(237, 181, 6)}
width={750}
height={1000}
/>
);
export default Color;
tools.ts
定义制作一个 base64 的像素点(最快)
// Pixel GIF code adapted from https://stackoverflow.com/a/33919020/266535
const keyStr =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
const triplet = (e1: number, e2: number, e3: number) =>
keyStr.charAt(e1 >> 2) +
keyStr.charAt(((e1 & 3) << 4) | (e2 >> 4)) +
keyStr.charAt(((e2 & 15) << 2) | (e3 >> 6)) +
keyStr.charAt(e3 & 63);
export const rgbDataURL = (r: number, g: number, b: number) =>
`data:image/gif;base64,R0lGODlhAQABAPAA${
triplet(0, r, g) + triplet(b, 255, 255)
}/yH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==`;