背景
失常的后端返回几十条数据数据间接渲染还好,然而当初需要是表格下面的每一行数据都要编辑的操作(各种下拉和输出),最初整体保留,保留实现后再次进来回显之前的曾经填的数据,当初的问题是每次回显比较慢(接口数据很快就返回了),在页面很卡顿,体验很不好。
问题排查
通过审查代码也没发现什么问题,找不出起因,代码逻辑是很简略的,就是等接口数据返回而后赋值给表格展现,到页面就 loading 了。。
问题解决
之前看到了列表能够切片渲染,就是前端对数据做一个分页而后依照程序加载,假如每个页面都有 limit 记录,那么数据能够分为 Math.ceil(total/limit) 个页面。而后能够应用 setTimeout 程序渲染页面,一次只渲染一个页面。
- 应用 setTimeout
const renderList(list = []){
const total = list.length
const page = 0
const limit = 200
const totalPage = Math.ceil(total / limit)
const render = (page) => {if (page >= totalPage) return
setTimeout(() => {for (let i = page * limit; i < page * limit + limit; i++) {const item = list[i]
if(item) {
// ... 这里写以后表格赋值逻辑
// this.tableData.push(item)
}
}
render(page + 1)
},0)
}
render(page)
}
- 应用 requestAnimationFrame 来代替 setTimeout
readerList(list = []) {
const total = list.length
const page = 0
const limit = 10
const totalPage = Math.ceil(total / limit)
const render = (page) => {if (page >= totalPage) return
for (let i = page * limit; i < page * limit + limit; i++) {const item = list[i]
if(item) {
// ... 这里写以后表格赋值逻辑
// this.tableData.push(item)
}
}
requestAnimationFrame(() => { render(page + 1) })
}
requestAnimationFrame(() => { render(page) })
}
对于 requestAnimationFrame
window.requestAnimationFrame() 通知浏览器——你心愿执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该办法须要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。
备注:若你想在浏览器下次重绘之前持续更新下一帧动画,那么回调函数本身必须再次调用 requestAnimationFrame()。requestAnimationFrame() 是一次性的。
requestAnimationFrame 比起 setTimeout、setInterval 的劣势次要有两点:
- requestAnimationFrame 会把每一帧中的所有 DOM 操作集中起来,在一次重绘或回流中就实现,并且重绘或回流的工夫距离紧紧追随浏览器的刷新频率,一般来说,这个频率为每秒 60 帧。
- 在暗藏或不可见的元素中,requestAnimationFrame 将不会进行重绘或回流,这当然就意味着更少的 cpu,gpu 和内存使用量。