乐趣区

html-js-大量数据优化

当页面渲染太多标签时,会出现卡顿的,典型就是类似 table 数据太多时,非常卡顿。如果选择分页,没必要讨论,这儿只讨论采用滚动的情况。解决思路很简单,就是页面不展示出来的元素,从页面上删除掉,最难点在于滚动条的处理,这儿分享一些细节思路,以上下滚动为例。

上下滚动表格

  1. 每一行固定高度,一次性获取所有数据。
  2. 每一行不固定高度,一次性获取所有数据。
  3. 每一行不固定高度,分批获取数据。

首先,布局如下:

当只显示可视区的内容时,overflow 的标签需要删除掉,但是删除了之后,滚动条会变化,甚至消失,因此可添加 padding-top 和 padding-bottom,以此模拟内容高度。

第一类,所有数据都能根据计算获得,需要一个 scrollTop 对应的显示数据的对照表,当滚动条位置变化时,去对照表种查看需要显示的数据,以此来渲染。当然不是每个 scrollTop 都去生成对照表,只需要某个范围生成就行了,比如:[{2000:显示数据}, {5000: 显示数据}](表示分别表示 0-2000,2000-5000 显示的数据)去对比第一个大于 scrollTop 的数据,获取其值,就是需要显示的数据。

* 这儿需要注意的是,显示数据必须有重复,且重复能占满屏幕以上,避免出现空白

第二类,就不好计算了,比如某一格里面内容太多,会令整行高度增加。可采用隐藏标签(opacity:0),循环渲染每一行,拿到那一行的高度。此种方式简单,也容易实现,不过计算渲染数据时,保证屏幕不出现空白的计算会复杂一点。隐藏标签渲染时,使用分批渲染,比如每次渲染 10 行,使用 requestAnimationFrame,setTimeout 或者 promise 处理一下,不至于卡死。

第三类,只知道当前数据是多少,无法计算总高度。可以采取与第二种类似的方式,使用隐藏标签计算出每一行的高度,最终计算出得到数据的总高度。当滚动条滚到某个值时,触发后续数据获取。一样的方式,重新计算出总高度。

所有方法都有个前提,就是每一行数据渲染是同步的,有些情况是先渲染出框,等获取数据后填充框。这种类似 table 的布局,会非常麻烦,需要设置一个回调函数,等所有数据渲染完成后再获取高度。

其他优化,如果是 vue,可以使用 Object.freeze() 冻结只需要显示的数据。

退出移动版