返回
一次聊透页面加载海量数据时如何保持丝滑体验?
前端
2024-01-14 02:30:00
大家都有过这样的体验,在我们的日常使用互联网服务时,加载某个页面的时候,当数据量非常庞大时,会让人有一种卡顿的感觉,甚至有的时候这个页面加载不出来就转圈圈,此时此刻,我们只有耐心等待着页面加载完才可以进行正常的操作,然而有时候这个时间会很久,让我们失去耐心,关闭这个页面。
造成这种问题的根源在于浏览器主线程,它会阻塞我们的JS事件循环,使我们无法在页面加载时进行任何操作。
解决这个问题的一个常见方法是使用Web Workers,它们允许您在后台运行JavaScript代码,而不会阻塞主线程。
另一个解决方案是使用延迟加载,这是一种将数据分成更小的块并在需要时加载它们的技术。这可以减少主线程的负载,并使页面加载更快。
但这些都是基于浏览器本身的层面,我们作为前端开发者,或者说前端优化人员,可以在前面对数据进行一些优化处理,这样可以让浏览器展现出来的加载更加友好,页面更丝滑。
比如,我们假设有20条数据要一次性填充到ul上,此时我们显然不适合这样做:
//假设存在ul元素,此处以伪代码表示
const ul = document.getElementById('list');
//20条数据使用循环的方式生成li并填充进去
for (let i = 0; i < 20; i++) {
const li = document.createElement('li');
li.textContent = `我是数据:${i}`;
ul.appendChild(li);
}
实践上述代码,我们发现界面体验很不友好,卡顿感严重。出现卡顿感的原因在于,循环会一次性将所有的li标签创建出来,并插入到ul中,在这个过程中,浏览器的主线程会处于阻塞状态,导致页面失去响应。
一种优化的方法就是将li元素的创建和插入过程分批次进行,比如:
const ul = document.getElementById('list');
//分批次插入数据,每批次10条数据
const batchSize = 10;
let start = 0;
let end = batchSize;
const timer = setInterval(() => {
//创建li并插入ul中
for (let i = start; i < end; i++) {
const li = document.createElement('li');
li.textContent = `我是数据:${i}`;
ul.appendChild(li);
}
//更新start和end的值,并判断是否所有数据已经插入
start += batchSize;
end += batchSize;
if (end > 20) {
clearInterval(timer);
}
}, 100);
分批次处理的方式,使得浏览器可以有更多的时间去处理其他任务,从而避免卡顿的现象。
在这个示例中,我们每隔100毫秒插入10个li元素,这使得浏览器有足够的时间来处理其他任务,而不会出现卡顿的现象。
最后,值得注意的是,分批次插入数据并不是唯一的解决办法,我们也可以使用其他的技术,比如:
- 使用虚拟DOM来创建和更新元素,这样可以减少对DOM的操作,从而提高性能。
- 使用Service Worker来缓存数据,这样可以减少从服务器加载数据的时间,从而提高性能。