实现高性能延迟加载的最新API:Intersection Observer

当你制作一个有许多图片需要在屏幕上加载的网站时,你应该注意它们在浏览器上的渲染性能。

如果在项目代码中使用React,则可以通过NPM或Yarn安装react-lazyload软件包。它的图片加载方式不同,所以使用这个包时可以期待更好的性能。

在这篇文章中,我将向您展示使用Intersection Observer的另一种延迟加载方式。

什么是IntersectionObserver

与多年前相比,Intersection Observer是用于检测性能更好的元素的新API,原因如下

我们先来看看如何使用这个API的例子后,再来深谈这个API。

api框架高性能(实现高性能延迟加载的最新API)(1)

Intersection Observer是一个两个数组的构造函数。它需要一个回调函数,每当它所监视的元素出现在浏览器中时,这个回调函数就会被启动,并且需要一个包含信息的可选对象,MDN文档。

为什么Intersection Observer更好?

当过去需要无限滚动时,因为需要检查滚动条当前位置的 getClientBoundingRect 会强制页面回流。

随着时间的推移,新的强大功能——Intersection Observer应运而生,推荐使用它进行无限滚动。但是,它仍然使用getClientBoundingRect 来获取它所观察的元素的位置。那为什么认为它更好呢?

Intersection Observer调用带有 requestIdleCallback 的回调函数,当当前 tick 期间没有任务运行时,该函数就会被启动。因此,尽管使用Intersection Observer的旧方式和新方式都可能导致回流,但Intersection Observer只在空闲期运行回调函数,因此在性能上更好。

正常的卡片视图

我使用随机图片选择器网站获取了随机图片,这是项目的基本结构。

api框架高性能(实现高性能延迟加载的最新API)(2)

本页面一次性加载约50张物品卡,在第一次渲染时也会加载约50张图片。

api框架高性能(实现高性能延迟加载的最新API)(3)

您可以从开发者工具检查“网络”标签上加载了多少张图片。在这种情况下,从67个网络请求中加载49个图像。幸运的是,网络请求的瀑布并不长,但你不应该有“哦,我不需要关心这些”这样的想法。

如果屏幕上需要渲染成千上万张图像该怎么办?轻松理解我观点的最好例子是思考Pinterest的工作原理。他们会在第一次看到的时候向你展示各种图片,每当你向下滚动到底部的时候——惰性加载。

那么如何使用Intersection Observer实现延迟加载?这很简单。设置触发回调函数的阈值,并使Intersection Observer API继续监视该元素。

const intersectionCallback = entries => { entries.forEach(entry => { // 如果元素在浏览器中显示的比例超过50% if (entry.intersectionRatio > 0.5) { // 图像加载... ... } }); } const IntersectionObserver = new IntersectionObserver(intersectionCallback, { threshold: [0.5], }); 复制代码

这是您可以传递到Intersection Observer的属性的列表。

懒加载卡片视图

在此示例的延迟加载中,仅当每张图片在屏幕上的显示比例超过50%时,才会加载每张图片。

现在,让我们看一下图像加载状态。

api框架高性能(实现高性能延迟加载的最新API)(4)

看到只有向下滚动时加载的图像计数在增加吗?由于使用了Intersection Observer,因此只有在适当的时候才允许浏览器加载图像。

浏览器支持

api框架高性能(实现高性能延迟加载的最新API)(5)

浏览器的支持范围还不错,但也不是那么好,因为IE根本不支持该API。但是不用担心! W3C为项目中需要此功能的人分发了IntersectionObserver的polyfill。

NPM中著名的Lazy-Load程序包

使用IntersectionObserver实现延迟加载组件非常简单,就像我之前在这篇文章中演示的那样。但是,您可能不想从头到尾实现它。有时您可能只想安装一个包。所以我要介绍一些有很多星星的NPM包。

总结

Intersection Observer是一个浏览器专用的功能,它可以让你实现懒加载。您可以惰性地加载图片或重磅内容,以减少用户看到内容所需等待的总时间。

不过,IntersectionObserver并不是所有的浏览器都完全支持,所以一定要检查polyfill,或者你可以考虑安装一个已经做好的包。

参考,