懒加载(滚动加载)

懒加载(滚动加载)
耳朵Strive懒加载(滚动加载)
- 在我们平常的开发中,我们会加载一些列表数据,这些数据的加载会影响到页面的加载速度,导致用户的等待时间变长,影响用户的体验
- 所以很多数据量比较大的列表数据都会有翻页的功能,但是翻页会让用户多一些操作,影响用户的体验
- 所以有一种懒加载的方式就是滚动加载,当用户滚动到列表的底部时,再加载下一页的数据,这样可以避免一次性加载所有数据,导致页面的加载速度变慢,同时也减少了用户的操作,提升了用户的交互体验
- 平时我常用的滚动加载主要是传统
scroll监听,但是最近深入研究了一下这个,发现还有其他的方法来实现滚动加载
基本原理
无论用哪种方法,逻辑都差不多:
- 监听滚动事件(
scroll或IntersectionObserver) - 判断是否接近底部
- 触发加载函数
- 请求数据并渲染
- 直到数据加载完成
两种常见实现方式
方式一:传统 scroll 监听
1 | <div id="list" style="height: 400px; overflow-y: auto;"> |
- 这种方式我们平时的使用频率还是挺高的,我就不做过多的介绍了
方式二:现代 IntersectionObserver
IntersectionObserver 可以观察某个元素是否进入视口,非常适合滚动加载的**“底部探针”**写法。
1 | <div id="list" style="height: 400px; overflow-y: auto;"> |
这种方式我以前是不了解的,但是最近在看一些文章的时候,发现这个方式还是比较常用的,所以我就来学习一下
首先我们先来了解一下
IntersectionObserverIntersectionObserver能异步地监听一个或多个目标元素(target)与某个容器(root,默认是浏览器视口)之间的交叉情况,比监听scroll更高效(浏览器内部优化、不会频繁回调),代码也更清晰。核心 API
1
2
3
4const observer = new IntersectionObserver(callback, options);
observer.observe(targetElement);
observer.unobserve(targetElement);
observer.disconnect(); // 停止观察所有目标callback(entries, observer):当被观察元素与 root 的交叉状态发生变化时被调用。entries是数组,每个entry是IntersectionObserverEntry,包含:entry.isIntersecting(布尔)——是否与 root 有交叉(大多数场景直接用它)entry.intersectionRatio(0~1)——可见比例entry.target、entry.boundingClientRect、entry.intersectionRect、entry.rootBounds、entry.time
options:root:容器元素(默认null= 浏览器视口)。如果你用滚动容器(overflow:auto),把它设为那个元素rootMargin:四边距(类似 CSS margin),可以用来提前触发(例如'0px 0px 200px 0px'表示在元素距离底部 200px 时就触发)threshold:触发阈值,单个数字或数组。例如0(一像素可见就触发),0.5(可见 50% 时触发),也可以是[0, 0.5, 1]
1
2
3
4
5
6const observer = new IntersectionObserver(entries => {
if (entries[0].isIntersecting) {
console.log('触发加载更多...');
loadMore();
}
}, { root: document.getElementById('list') });这个地方很多人第一次用
IntersectionObserver都会疑惑,为啥大多数例子里都是entries[0]entries到底是什么这是浏览器在调用你写的 callback 时传进来的第一个参数
它是一个 数组(准确地说是
IntersectionObserverEntry[])这个数组里包含了 当前这个观察器里,所有交叉状态发生变化的元素 对应的 entry 对象
如果你只用
observe()观察 一个元素,那么一次回调里entries数组里 通常只有一个元素,所以大家就直接写entries[0]如果你用一个 observer 观察了 多个元素,那么一次回调可能有多个元素变化(比如同时两个元素进入视口),这时
entries里就会有多个 entry
为什么一般直接用
entries[0]- 因为大部分场景(比如无限滚动)只观察一个“探针元素”,数组里就只有一个 entry,直接取第一个就够了,写起来方便,但这并不是强制规则,只是“偷懒”的写法
在Vue项目中使用VueUse来快速实现滚动加载
VueUse 中可以使用
useInfiniteScroll实现滚动加载用来实现无限滚动加载,封装了
scroll事件监听和触发条件判断原理是:监听容器的滚动位置,当接近底部时触发你定义的回调
1 | <template> |












