博客之前集成了Douban数据的展示功能,不过由于数据一次性加载过多,且都是有图片的数,导致在进入该网页时会使浏览器卡死3-5秒,等到图片完全加载完毕后才能正常操作,非常影响用户体验。
我检查了一下,发现卡顿的原因主要还是一次性发起的图片加载请求太多了,查了下资料,似乎下一代的HTTP2.0协议好像对这方面做了优化。但是常规做法还是使用懒加载来处理,也就是滚到图片位置才进行图片请求。
不过我不太想使用第三方的库来处理这个问题,其他库用起来麻烦,而且很臃肿,我其实只要简单的实现这个功能就好了。之前在移植Smart主题的TOC功能到二〇一九上时发现他使用了 IntersectionObserver
这个函数来处理,便查了一下这个函数的介绍:
Intersection Observer API 提供了一种异步检测目标元素与祖先元素或 viewport 相交情况变化的方法。
这个函数多用于以下几种情况
- 图片懒加载——当图片滚动到可见时才进行加载
- 内容无限滚动——也就是用户滚动到接近内容底部时直接加载更多,而无需用户操作翻页,给用户一种网页可以无限滚动的错觉
- 检测广告的曝光情况——为了计算广告收益,需要知道广告元素的曝光情况
- 在用户看见某个区域时执行任务或播放动画
后查了一些范例,便参照这个教程的实现了图片的懒加载功能
原理其实很简单
- 先修改你的所有图片,将img元素的src属性指定为空或者一个展位图,然后添加的一个data属性存放图片链接,如
data-src
,添加lazyload
类用于之后可以获取到图片。 - 通过之前设置的类名获取所有需要懒加载的图片元素。
- 创建一个IntersectionObserver对象,并传入一个处理函数和rootMagin
- 处理函数的主要内容是检测被观测到的对象的
isIntersecting
(如果isIntersecting
为真,则该图片至少已经达到我们设置的rootMargin值以内) 判断,如果进入了目标区间内则将img的data-src设置为src属性。 - 并通过调用
unobserve
停止对这个片检测。
我记得以前实现起来挺复杂的,现在有了个函数只需要简单的几行代码就可以实现,真的方便。
END
🥳
后续:主题修改完上传到服务器后发现还是会出现卡死的情况,通过使用Chrome的性能工具发现pangu.autoSpacingPage()阻塞了进程...。
🥳
后续2:根据「剑公子 」的留言,现代浏览器已经原生支持懒加载,只需要在img标签中添加属性
loading="lazy"
即可。通过性能检测工具可以发现 spacingNode
、 spacingNodeByXPath
阻塞了进程,不知道是什么原因。我尝试将调用函数换成 spacingPageBody()
后页面性能恢复正常。可能是body之外的某些标签阻塞了函数执行。