大数据问题

134 阅读3分钟

大数据

日常开发我们经常会遇到一些相关需求:

  • 给你类似上万条数据让你渲染(table,list, select)
  • 支持上述列表模糊查询等

大数据常见的技术方案

  • 正常返回数据渲染,不做任何处理
import React, { useEffect, useState } from 'react'

function App() {
  const now = Date.now()
  const deallist = () => {
    let list = []
    const total = 10000

    for (let index = 0; index < total; index++) {
      const item = {
        value: index,
        key: `${index}-1`
      }
      list.push(item)
    }
    return list
  }

  console.log(Date.now() - now) //耗时: 157
  setTimeout(() => {
    console.log(Date.now() - now) //耗时: 32200
  }, 0)
  return (
    <div className="App">
      <ul>
        {deallist().map(item => {
          return <li key={item.key}>{item.value}</li>
        })}
      </ul>
    </div>
  );
}

export default App;

我们对十万条记录进行循环操作,JS的运行时间为157ms,但是最终渲染完成后的总时间确是2800ms

原因

在 JS 的Event Loop中,当JS引擎所管理的执行栈中的事件以及所有微任务事件全部执行完后,才会触发渲染线程对页面进行渲染(事件机制)

对于大量数据渲染的时候,JS运算并不是性能的瓶颈,性能的瓶颈主要在于渲染阶段

  • 定时器分批请求数据
 const loop = (curPages, curIndex) => {
  let ul = document.getElementById('ul')
    if (curPages <= 0) {
      return false
    }
    let pageCount = Math.min(curPages, pageSize)
    setTimeout(() => {
      for (let i = 0; i < pageCount; i++) {
        let li = document.createElement('li')
        li.innerText = curIndex + i
        ul.appendChild(li)
      }
      loop(curPages - pageCount, curIndex + pageCount)
    }, 0)
  }

页面加载的时间已经非常快了,每次刷新时可以很快的看到第一屏的所有数据,但是当我们快速滚动页面的时候,会发现页面出现闪屏或白屏的现象

**原因: **

刷新频率受屏幕分辨率和屏幕尺寸的影响,因此不同设备的刷新频率可能会不同,而setTimeout只能设置一个固定时间间隔,这个时间不一定和屏幕的刷新时间相同。

  • 滚动加载

  • 用div把Table包起来

  • Table添加属性scroll={{y: 200, x: 'max-content'}},使其可以滚动

  • 给包裹用的div打上ref印记

  • 在div上监听滚动onScrollCapture

注意

但是滚动加载还是会有问题: 因为滚动加载以后,数据慢慢会累积,然后渲染的时候我们dom还是相对庞大,也会出现卡顿现象

  • 分页

image.png

其实分页查询的话到最后查数据库,后面查的数据的偏移量和最大的记录行数目越大,其实性能也会有影响的

可以参考: www.jianshu.com/p/864d0bd80…

  • 虚拟列表 虚拟列表的实现,实际上就是在首屏加载的时候,只加载可视区域内需要的列表项,当滚动发生时,动态通过计算获得可视区域内的列表项,并将非可视区域内存在的列表项删除。

  • 计算当前可视区域起始数据索引(startIndex)

  • 计算当前可视区域结束数据索引(endIndex)

  • 计算当前可视区域的数据,并渲染到页面中

  • 计算startIndex对应的数据在整个列表中的偏移位置startOffset并设置到列表上

image.png

image.png

image.png

关于table的大数据虚拟解决方案

涉及的问题

  • 展开收缩性能
  • 编辑表格性能

已有的npm包

  • ali-react-table

image.png

  • antd自带的大数据例子

image.png

image.png

  • virtualizedtableforantd4

image.png

image.png

  • react-virtualized

image.png

image.png

参考: juejin.cn/post/698623…

mp.weixin.qq.com/s/gkPOmKKD2…

juejin.cn/post/700359…

github.com/dwqs/blog/i…

参考文档: juejin.cn/post/700092… juejin.cn/post/684490… www.jianshu.com/p/56b74571d… juejin.cn/post/684490… juejin.cn/post/684490… zhuanlan.zhihu.com/p/147178478

juejin.cn/post/711058…