如何实现图片懒加载与无限滚动?

539 阅读3分钟

说起懒加载,我想你一定只记住了import()动态加载或者是react.lazy(),是不?

那如果我要在页面滚动的时候,加载很多图片呢?或者长列表数据呢?

有没有办法自己实现一个呢?

今天我要带大家一起实现一个滚动到了才加载图片的懒加载方法,还是用最粗陋的代码,没有任何框架,直接实现,我相信没有框架的代码你都会敲,那在框架里面开发不更加轻而易举么,从框架里面逃出生天,才能提升自己的技术能力。相信我,你每走的一步,都作数!

实现的方法有三种:

1.监听 scroll 事件

主要利用html5的data属性来给标签自定义属性,然后当元素款要进入视口的时候,我就要赶紧把data-src的属性值赋值给src,此时浏览器会进行重排,渲染图片。

image.png

执行代码:npx http-server 你也可以

image.png

爱用哪个就用哪个吧,随自己的喜好走,我也不会强迫大家非http-server不可。打开浏览器看看:

image.png

2.Intersection Observer API 监听元素距离视口的位置

最初的时候,瀑布流呀,加载长列表,都是用监听scroll实现的,但是在滚动的时候会获取元素的位置,每获取一次offsetTop,Height 等数据就会引发一次重绘,当图片比较大且多的时候,每滚动一下就遍历一次,明显有性能问题,为了解决这个问题,就引入了 Intersection Observer API - Web API 接口 |MDN的 (mozilla.org) 反正现在的浏览器都去 ie 化了,咱们可以放心大胆的使用它。

image.png

具体的使用如下:

image.png

image.png

解释下代码:就是创建一个 IntersectionObserver 对象,然后在这个对象的构造函数里面做:当元素进入视口以后,我要干些啥,事情做完要记得用 observer.unobserve(img) 解绑,以免占用内存,不能释放。对象创建好以后,我们要去拿元素,然后把每个元素都和 observer 对象绑定在一起,要 observer 去监听它有没有进入视口。

效果如下:

image.png

代码非常简单,用起来也比较清爽,现在很多懒加载都是用这个技术实现的,大家赶紧用起来吧!他的优点就是解决了所有scroll的痛点。

3. 浏览器原生loading="lazy"属性

你真的没有看错呀,只要给标签加上loading="lazy"属性,浏览器就会帮我们自动实现懒加载的效果,不需要任何js代码,是不是很完美呀,不过你也别高兴的太早了,它只支持 img,iframe 这两个标签,其他如:<video><picture>、CSS background-image 等都不支持。

不过开心的是,浏览器支持度还是比较高的,反正去ie化了,ie完全忽略即可。

image.png

用法:

<img loading="lazy" src="example.jpg" alt="Example Image" />

<iframe loading="lazy" src="https://github.com/JuniorTour"></iframe>

性能对比下看看,有没有变化:

我在html里面放了一千个图片加载,没有放loading=“lazy”,然后npx http-server 启动页面,用 LightHourse 监控,得出的性能如下:

image.png

image.png

然后把这个几千个img 加上 loading="lazy" 再次测试看看

image.png

性能指标确实发生了变化,因为我们的测试代码本就很简单,所以性能变化很小,你可以在自己的实际项目里面,跑一下看看呗。