likes
comments
collection
share

第六十期:前端一次渲染30000条数据难吗

作者站长头像
站长
· 阅读数 43

这里记录工作中遇到的技术点,以及自己对生活的一些思考,周三或周五发布。

封面图

第六十期:前端一次渲染30000条数据难吗

很明显,难,是真的难!不是一般的难!

关于前端性能优化,有很多文章写的都很详细,大体内容都是减少dom操作,压缩代码文件,减小图片,使用cdn之类的。这些都是一些普遍的问题,因为从根本来看,影响前端性能的因素有三点,一是网络带宽,二是接口返回时间,三是界面渲染速度。

这三点中,前两个问题我觉得可以划分为一类问题,真正跟前端关系比较密切的是界面渲染速度。那么界面渲染速度取决于什么呢?

一般来说,我们会想到dom元素,dom元素越多,界面渲染的时间越长。这个我们都知道,但是其实我们忽略了一个比较重要的点:目前前端开发中主要使用Vue及React框架。这两种框架都是基于数据驱动的,所以我们在渲染列表或者表格时,影响界面渲染效率的因素其实是数据的计算时间。

那么是什么影响了数据的计算时间呢?很明显,数据量和js的执行效率。数据量越小,js的执行效率越高,计算结果返回的就越快,界面渲染的时间就越短。数据越大,js的执行效率越低,界面渲染的时间就越长。

js的执行效率一般我们可以理解为js循环的效率,我们可以将它看作成一个固定值。执行下面的代码,大致需要5s钟时间:

function test(){
  let start = performance.now()
  for(let i=0;i<30000;i++){
    console.log('i')
  }
  let end = performance.now()
  
  console.log(end-start) // 5000ms
}

这只是个简单的循环30000个数值,循环体中并没有其他复杂的操作,但是当我们的循环体中有其他复杂的操作,比如判断,对象赋值,或者嵌套一层或多层内循环时,花费的时间则呈现出指数级的增长。

尤其是当单条数据中的属性不固定的时候,一般来说,我们遇到的表格,单条数据里面属性十几,一二十个就算多的了,但是有时候可不止一百个!

是的,你没有看错,不止一百个!这个时候,遍历一个数组,数组长度28000,单条数据属性100个,那你只能等,没有办法。

举个现实中的例子:

最近做的项目中有一个多栏表头的表格,表头的数量不固定,表头分组的数量也不固定,表头最多有720列,每个表头分组中最多有8列,分组表头需要动态计算,表格数据也需要前端动态计算,这样算下来,一条数据中最多会有7208n个字段,n是必须的字段,并且后端没有分页,一次性返回30000条数据。

这种情况下,靠前端优化,你怎么优化?这个时候,你会发现,一旦数据量超过某个临界值,界面九成的概率是要崩溃掉的,即便不崩溃,也需要等个十几分钟。

也许有人会说,这种情况用什么切片了,数据分组了。数据分组其实就是分时函数,比如原先你一次性生成10000条数据,那么现在每秒钟生成500条。这种效果在上面的场景中其实起到的优化的效果也并不明显,但是也没什么特别好的方法。

我这里的分时函数是这样的:

const genTableDataSource = (arr) => {
        let obj = {}
        if (arr.length) {
          arr.map((item) => {
            data.xAxis.map((v) => {
              if (item.dimension === v.dimension) {
                obj.store_name = item.store_name
                for (let k in coreIndexListObj) {
                  obj[`${v.title}${coreIndexListObj[k].field}`] =
                    item[coreIndexListObj[k].field]
                }
              }
            })
          })
        }
        tableDataSource.push(obj)
        console.log('tableDataSource---', tableDataSource)
      }
      
const timeChunk = (arr, fn, count) => {
        let keys = Object.keys(arr),
          t
        const start = () => {
          for (let i = 0; i < Math.min(count || 2, keys.length); i++) {
            let obj = arr[keys.shift()]
            console.log('obj---', obj)
            fn(obj)
          }
        }
        return function() {
          self.timer = setInterval(() => {
            if (keys.length == 0) {
              clearInterval(self.timer)
            }
            start()
          }, 500)
        }
      }

      let genFinal = timeChunk(rebuildList, genTableDataSource)
      console.log('genFinal--', genFinal)
      genFinal()

个人感觉前端性能优化这个问题,还是需要具体问题具体分析,在一般的项目里,真的有那么多场景需要去优化吗,这个未必,但是我们需要针对一些特定的场景有自己的解决方案。

可以从技术上进行优化,分页,图片压缩,web缓存,nginx缓存,cnd等等。也可以结合非技术方案,优化交互方案,减少业务复杂度等等。

总之,关于性能优化这个东西,需要根据具体情况具体分析,不能人云亦云。

最后

  • 公众号《JavaScript高级程序设计》
  • 公众号内回复”vue-router“ 或 ”router“即可收到 VueRouter源码分析的文档。
  • 回复”vuex“ 或 ”Vuex“即可收到 Vuex 源码分析的文档。

感谢您的点赞,转发,关注。

转载自:https://juejin.cn/post/7062526457607634958
评论
请登录