使用requestAnimationFrame对列表切片进行渲染(超简单)

背景

正常的后端返回几十条数据数据直接渲染还好,但是现在需求是表格上面的每一行数据都要编辑的操作(各种下拉和输入),最后整体保存,保存完成后再次进来回显之前的已经填的数据,现在的问题是每次回显比较慢(接口数据很快就返回了),在页面很卡顿,体验很不好。

问题排查

通过审查代码也没发现什么问题,找不出原因,代码逻辑是很简单的,就是等接口数据返回然后赋值给表格展示,到页面就loading了。。

问题解决

之前看到了列表可以切片渲染,就是前端对数据做一个分页然后按照顺序加载,假设每个页面都有 limit 记录,那么数据可以分为 Math.ceil(total/limit) 个页面。然后可以使用setTimeout顺序渲染页面,一次只渲染一个页面。

  1. 使用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)
}
  1. 使用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和内存使用量。
作者:fuGUI原文地址:https://segmentfault.com/a/1190000043821073

%s 个评论

要回复文章请先登录注册