问题背景
在开发网站时,如果使用原生img标签渲染,会在页面加载后,内容出现偏移抖动的情况,给用户带来不好的体验;如下图(测试文本在上方先出来,待图像加载后又被顶到了下方)
解决方式
如果使用nextjs开发的话,可以使用image标签来解决上述问题;
使用Image替换img,
代码如下:
import Image from "next/image";
import test from "./test.jpg";
const Test = (props) => {
return (
<div>
{/* <img src="./test.jpg" style={{ width: "100%", height: "auto" }} /> */}
<Image
{...test}
alt="猩猩图"
placeholder="blur"
style={{ width: "100%", height: "auto" }}
/>
<div>我的测试</div>
</div>
);
};
效果如下:
可以发现现在文字渲染后到网页load完成过程中,位置没有偏移;并且优化了图片的加载体验;观察nextjs返回的HTML,和网络请求,可以看到src被替换成了一个像素模糊的图片,这个图片体积很小,待大图加载完后再替换它;
更进一步
到目前为止,我们都是使用的都是本地图片,那么换成远程图片后又该如何做呢?
这就需要我们自己来生成placeholder的图片了,这里可以使用lqip-modern这个库;
用法如下:
const Test = (props) => {
return (
<div>
{/* <img src="./test.jpg" style={{ width: "100%", height: "auto" }} /> */}
<Image
{...props}
alt="猩猩图"
placeholder="blur"
style={{ width: "100%", height: "auto", color: "red" }}
/>
<div>我的测试</div>
</div>
);
};
export const getStaticProps = async () => {
const lqip = require("lqip-modern");
const url = "https://xxxx.aliyuncs.com/test.jpg";
const imgData = await fetch(new URL(url));
const arrayBufferData = await imgData.arrayBuffer();
const result = await lqip(Buffer.from(arrayBufferData));
console.log({ result });
return {
props: {
blurDataURL: result.metadata.dataURIBase64,
blurWidth: 16,
blurHeight: 4,
width: result.metadata.originalWidth,
height: result.metadata.originalHeight,
src: url,
},
};
};
效果如下: