Cirry's Blog

在Astro中实现图片懒加载

2023-02-15
astro
astro
最后更新:2024-04-18
4分钟
603字

思考

关于图片懒加载的方法,基于Intersection Observer API实现起来很简单。

但是在Astro中实现起来却不同,因为这里要实现的不是网站上的图片懒加载,而是博客中图片的懒加载。

Astro中的博客是使用Markdown写的,在Frontmatter中添加layout来指定渲染的组件,我们在打开博文的时候,组件已经加载。博文中的image标签都有了src属性,已经去发送请求获取数据了。

我一开始的想法是,在打开页面之后,图片发送请求之前,找到一个钩子函数,把image的src属性删除,存到data-src中。一个比window.onload更早的钩子函数,但是没有这样的方法。

所以我就想在把markdown渲染成html的时候,把image标签进行处理。这个思路应该是可行的,我就去翻看Astro的文档,还真找到了配置方法markdown.remarkPlugins

顺着官网的线索在github中找,我找到了这个包:remarkjs/remark,里面介绍了一段代码示例可以将h标签的层级缩小一级,即h2标签会变成h3标签。

1
import { visit } from 'unist-util-visit'
2
3
function myRemarkPluginToIncreaseHeadings() {
4
return (tree) => {
5
visit(tree, (node) => {
6
if (node.type === 'heading') {
7
node.depth++
8
}
9
})
10
}
11
}

原始md文档:

1
# Hi, Saturn!

页面html为:

1
<h1>Hi, Saturn</h1>

格式化后,页面html为:

1
<h2>Hi, Saturn</h2>

从上面的示例中,我感觉到这个插件能够满足需求,于是开始动手实现。

实现

astro.config.mjs中添加如下代码:

1
import { visit } from 'unist-util-visit'
2
3
function myRemarkPluginToLazyLoadImage() {
4
return (tree) => {
5
visit(tree, (node) => {
6
if (node.type === 'image') {
7
// 将url属性给alt,另外清空url,这样页面加载的时候,图片没有url属性就不会加载
8
node.alt = node.url
9
node.url = ''
10
}
11
})
12
}
13
}
14
15
export default defineConfig({
7 collapsed lines
16
..., // 其他配置
17
markdown: {
18
remarkPlugins: [myRemarkPluginToLazyLoadImage],
19
// 一定要加上这个,否则不会把md处理为html,而只处理插件内的代码
20
extendDefaultPlugins: true,
21
}
22
})

在引入md的astro组件中,添加如下代码:

1
<script>
2
/* 查找到博客中的所有img标签 */
3
var markdownBody = document.querySelector(".markdown-body");
4
let images = markdownBody.querySelectorAll("img");
5
6
const callback = (entries) => {
7
entries.forEach((entry) => {
8
if (entry.isIntersecting) {
9
const image = entry.target;
10
const data_src = image.getAttribute("alt");
11
image.setAttribute("src", data_src);
12
observer.unobserve(image);
13
}
14
});
15
};
7 collapsed lines
16
/* 给每个img标签添加监听方法 */
17
const observer = new IntersectionObserver(callback);
18
images.forEach((image) => {
19
observer.observe(image);
20
});
21
}
22
</script>

到这里,我们的图片懒加载就完成啦!

本文标题:在Astro中实现图片懒加载
文章作者:Cirry
发布时间:2023-02-15
版权声明:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
感谢大佬送来的咖啡☕
alipayQRCode
wechatQRCode