Skip to content

项目速度优化

作者:Yuan Tang
更新于:5 个月前
字数统计:617 字
阅读时长:2 分钟

需要原因

如果一个长时间运行的 JS 操作,可能会阻塞浏览器的渲染,这样我们页面就看不到反应,导致长时间白屏,或者页面不展示任何效果。

解决方法为把操作切成一片一片的,先操作一片,操作完后渲染,再操作下一片。

用一副图例来说明如下:

图例

例如,我要渲染一个表格,该表格有50000条数据,则光是渲染和滑动就有很明显的卡顿现象。代码如下:

js
const dateArr = reactive([])

for (let i = 0; i < 50000; i++) {
  dateArr.push({
    id: 1,
    name: '张三',
    status: Math.floor(Math.random() * 3),
    checked: false
  })
}

RequestAnimation

requestAnimation 定义的任务,会在浏览器渲染完成后去执行。所以我们只需要把每个切片放到 requestAnimation 。它在执行完一个后,会等着浏览器渲染完成再执行下一个。

下面通过代码来实现这一思想,还是以上方案例为例:

js
let index = 0
function sliceRender() {
  requestAnimationFrame(() => {
    const target = index + 500
    for (; index < target; index++) {
      dateArr.push({
        id: 1,
        name: '张三',
        status: Math.floor(Math.random() * 3),
    		checked: false
      })
    }

    if (index < 50000)
      sliceRender()
  })
}

sliceRender()

上方代码利用时间切片的思想,先切出 500 条数据,渲染成功到页面上后再获取后续的数据,此时页面用户在看前500条数据,后续的数据在悄悄渲染。这样就不会有卡顿的效果。

选择全部也是这个道理,选择全部的功能是把所有列表的 id 添加到所选数组内,而一次性把50000条数据都一次性添加到数组中需要一定的时间消耗。因此可以利用切片的思想,切片添加数据。

代码如下所示:

js
// 点击全选复选框
function selectAllFn(e) {
  choseList = []
  let index = 0
  function choseAllID() {
    if (e.target.value) {
      requestAnimationFrame(() => {
      	for (; index < target; index++) {
          const target = index + 500
      		choseList.push(dateArr[index.id])
        }
        if (index < dateArr.length)
          choseAllID()
    	})
    }
  }

  choseAllID()
}

总结

在优化项目时,不只是要追求绝对的速度提升,在无法进一步提升时可以想办法让用户体验更好。

比如时间切片,异步异步加载,这些操作对整体速度都没有提升,但是通过合理安排顺序,可以让体验更好。

除了这次的表格案例,另一个如多个 echarts 表图渲染案例也可以适用。多个图绘制太慢,可以先绘制一个,完成后再绘制一个。

Contributors

Yuan Tang