前言
最近公司项目快结项了,但是我发现公司的每个页面打开都比较卡,究其原因数据量大,请求多,渲染慢。加之面试的时候也遇到过此类问题,那么今天就来尝试去实现一下。
一、整理思路
首先我们要知道js处理大量数据并没有花费多长时间。耗时最长的是渲染dom元素。一次加载完需要耗费大量时间,所以我们可以把数据切割成一个个小块。每次渲染一小块就能够将dom渲染出来了。
二、代码实现
<ul></ul>
// 第一种实现方式
const $UL = document.querySelector('ul')
let size = 0
const myList = getList()
// 生成数据
function getList() {
let list = []
for (let i = 0; i < 5005000; i++) {
list.push(i)
}
return list
}
function render(list) {
let tempBox = document.createDocumentFragment()
list.map(function (data) {
let li = document.createElement('li')
li.innerHTML = data
tempBox.appendChild(li)
})
$UL.append(tempBox)
}
function splitList() {
if (size + 100 < myList.length) {
render(myList.slice(size, size + 100))
size += 100
requestAnimationFrame(splitList)
} else {
render(myList.slice(size, size + myList.length - size))
size = myList.length - size
}
}
requestAnimationFrame(splitList)
可能有些同学没用过[requestAnimationFrame],(https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestAnimationFrame),建议先去了解一下,当然你也可以用计时器来代替,不写也是可以的。
三、优化代码
虽然上诉方式已经将渲染时间缩短了,但是我们想要的效果是,需要的时候再渲染这个元素,不需要/被隐藏的元素就不渲染。那么这该怎么实现呢,首先我们去监听进度条,根据进度条滚动的距离,渲染dom,那么上诉代码就会变成如下样子。
<ul style="overflow: auto; height:400px;"></ul>
const $UL = document.querySelector('ul')
let page_arg = {
size: 0,
count: 100,
}
const myList = getList()
$UL.onscroll = function () {
if (this.scrollTop + this.clientHeight + 10 >= this.scrollHeight) {
splitList()
}
}
// 生成数据
function getList() {
let list = []
for (let i = 0; i < 10000000; i++) {
list.push('我是数据'+i)
}
return list
}
function render(list) {
let tempBox = document.createDocumentFragment()
list.map(function (data) {
let li = document.createElement('li')
li.innerHTML = data
tempBox.appendChild(li)
})
$UL.append(tempBox)
}
function splitList() {
render(myList.slice(page_arg.size, page_arg.size + page_arg.count))
page_arg.size += page_arg.count
}
splitList()
总结
写到这里渲染数据列表的问题就算是结束了,如果有什么地方写的不对,或者还能优化的地方还请各位大佬指出来,毕竟我也是第一次尝试渲染这么多数据,代码在这里,各位也可以自己去尝试一下。其实还可以在优化一下这个计算的时间,可以使用web Worker多开一个线程来协助计算,再次将js的计算时间压缩,不过对我来说已经足够了,对于追求性能的同学可以去尝试一下。然后分享一下自己的心得。嘿嘿,ok,这篇博客就到此为止了,谢谢各位的支持,有问题请私信我。
转载:https://blog.csdn.net/weixin_43889562/article/details/113128957
查看评论