无限滚动实现详解与实战中遇到的那些坑
优化前:卡得不行
最近我在做一个项目,需要实现一个无限滚动的页面。一开始我用的是比较简单的实现方式,就是每次滚动到底部时,通过AJAX请求获取新的数据,然后动态添加到页面上。结果呢,优化前卡得受不了,用户滚动页面时,动不动就卡顿,体验极差。
找到毛病了!
为了解决这个问题,我先用了一些工具来定位问题所在。主要是用了Chrome的开发者工具,尤其是Performance面板,记录了一次完整的滚动过程,发现主要问题是DOM操作太多,每次加载新数据时都要重新渲染大量元素,导致浏览器压力大,性能下降。
另外,我还发现网络请求频繁,每次加载的数据量也不小,这也拖慢了页面响应速度。
优化后:流畅多了
经过一番折腾,我试了几种方案,最后这个效果最好。下面我分享一下具体的优化方法。
减少DOM操作
首先,我要解决的是DOM操作过多的问题。原来的代码是这样的:
window.addEventListener('scroll', function() {
if (isBottom()) {
fetch('https://jztheme.com/api/data')
.then(response => response.json())
.then(data => {
const container = document.getElementById('data-container');
data.forEach(item => {
const div = document.createElement('div');
div.textContent = item.name;
container.appendChild(div);
});
});
}
});
这里每次加载新数据时,都要创建多个DOM元素并逐个添加到容器中,效率非常低。我改成了批量插入DOM元素的方式,这样可以减少重绘次数:
window.addEventListener('scroll', function() {
if (isBottom()) {
fetch('https://jztheme.com/api/data')
.then(response => response.json())
.then(data => {
const container = document.getElementById('data-container');
const fragment = document.createDocumentFragment();
data.forEach(item => {
const div = document.createElement('div');
div.textContent = item.name;
fragment.appendChild(div);
});
container.appendChild(fragment);
});
}
});
这样优化后,DOM操作明显减少,性能提升了不少。
懒加载图片
除了DOM操作,我还注意到页面中的图片也是性能瓶颈之一。于是我引入了懒加载机制,只有当图片进入视口时才加载它们。原代码是这样的:

优化后的代码如下:
![Image 2]()
然后在JavaScript中初始化懒加载库:
import lazySizes from 'lazysizes';
document.addEventListener('DOMContentLoaded', () => {
lazySizes.init();
});
这样,图片加载不会阻塞页面滚动,性能也得到了显著提升。
优化网络请求
最后,我还优化了网络请求。原来每次请求的数据量较大,导致加载时间较长。我将每次请求的数据量减小,并且使用了缓存策略,避免重复请求相同的数据。
原来的代码是这样的:
fetch('https://jztheme.com/api/data?limit=50')
.then(response => response.json())
.then(data => {
// 处理数据
});
优化后的代码如下:
const API_URL = 'https://jztheme.com/api/data';
const cache = new Map();
function fetchData(page) {
if (cache.has(page)) {
return Promise.resolve(cache.get(page));
}
return fetch(${API_URL}?page=${page}&limit=10)
.then(response => response.json())
.then(data => {
cache.set(page, data);
return data;
});
}
window.addEventListener('scroll', function() {
if (isBottom()) {
const nextPage = getNextPage();
fetchData(nextPage).then(data => {
// 处理数据
});
}
});
通过这种方式,不仅减少了每次请求的数据量,还利用了缓存机制,提升了整体性能。
性能数据对比
经过这些优化后,性能有了明显的提升。具体数据如下:
- 优化前:加载时间平均5秒
- 优化后:加载时间平均800毫秒
从数据上看,性能提升了近6倍,用户体验也好了很多。
总结
以上是我的优化经验,主要集中在减少DOM操作、懒加载图片和优化网络请求三个方面。希望对你有帮助。如果有更好的方案,欢迎评论区交流。

暂无评论