• 请不要在回答技术问题时复制粘贴 AI 生成的内容
qzhai
V2EX  ›  程序员

前端一般处理海量数据的渲染有什么优化方案

  •  
  •   qzhai · Jan 17, 2020 · 6785 views
    This topic created in 2314 days ago, the information mentioned may be changed or developed.

    假设,页面需要在一个表格里渲染 几万条 数据。在不分页的情况下有什么好的优化方案来保证页面的流畅度。

    (可能例子有些极端)

    Supplement 1  ·  Jan 17, 2020
    好吧,问题升级,加入我的数据结构很复杂,切渲染的数据高度不一致。

    比如 我有超多条数据是依据某个维度进行分组展示的,每条数据可能还会有父子关系需要在渲染中体现。
    其次它们的高度又不是统一,甚至会有多媒体比如图片的存在(图片又需要在加载后才知道高度)。
    因为是按某个维度进行分组,所以不能分页。
    所以这么复杂的一堆数据需要展示在一个页面里。
    有什么好的优化方案么。
    35 replies    2020-01-19 09:15:36 +08:00
    Sapp
        1
    Sapp  
       Jan 17, 2020
    虚拟列表,简单来说就是 1w 条列表,每次只渲染一部分,之后滚动的时候实时渲染出新的来模拟滚动,这样 dom 实际就是几十条的样子,网上有很多现成的方案
    shijianit
        2
    shijianit  
       Jan 17, 2020
    在滚动事件里面做判断,屏幕外面的数据,元素就删除,只保留高度
    zhuzhibin
        3
    zhuzhibin  
       Jan 17, 2020 via iPhone
    貌似都在说 lazy load ?
    fancy111
        4
    fancy111  
       Jan 17, 2020
    一个表里面几万条? 能看得完吗?为何不分批
    qzhai
        5
    qzhai  
    OP
       Jan 17, 2020
    @shijianit 加入,数据嵌套循坏,带子数据,或者每条数据的高度不一致,内容带图片的话判断起来岂不是很麻烦,
    Mozshaw
        6
    Mozshaw  
       Jan 17, 2020
    关键词:virtual scroll
    可参考 https://github.com/tangbc/vue-virtual-scroll-list
    zaynex
        7
    zaynex  
       Jan 17, 2020
    @qzhai 假设高度不一致的话,这种虚拟列表应该是没法用了。嵌套的数据结构可以利用 web worker 在里面转换成平铺的数组,每次增量渲染若干个节点。
    qzhai
        8
    qzhai  
    OP
       Jan 17, 2020
    @Mozshaw 如果渲染数据高度不一致,或者数据结构发复杂 需要提现层级关系比如嵌套 这种有啥好的解决办法么
    momocraft
        9
    momocraft  
       Jan 17, 2020
    高度不一致时虚拟列表可能会有什么问题?比如滚动条不准?
    zhw2590582
        10
    zhw2590582  
       Jan 17, 2020
    之前也遇到过这个问题,用了这个: https://github.com/bvaughn/react-virtualized
    qzhai
        11
    qzhai  
    OP
       Jan 17, 2020
    @momocraft 虚拟列表是通过高度来计算出当前 可视区域内的数据的。如果高度不一致就无法计算可视区域内究竟有多少数据以及是什么数据,也就不能来删除或者渲染数据。
    zhw2590582
        12
    zhw2590582  
       Jan 17, 2020
    不过 react-virtualized 的默认是高度要一致,假如高度不一致需要自己提前计算出来再传值到组件里。
    lovedebug
        13
    lovedebug  
       Jan 17, 2020
    redbuck
        14
    redbuck  
       Jan 17, 2020
    @qzhai 这种类库应该有刷新机制吧,手动刷新下.类似 iscroll,better-scroll 的 refresh.
    diveIntoWork
        15
    diveIntoWork  
       Jan 17, 2020
    双缓冲
    linghucq1
        16
    linghucq1  
       Jan 17, 2020
    https://juejin.im/post/5de71d1b6fb9a01610795250

    不去计算每一项的高度, 而是计算整页的高度, 虽然封装成组件了, 但是没有实际在项目中使用过...
    ccraohng
        17
    ccraohng  
       Jan 17, 2020 via Android
    不是有支持动态高度的么,类似 CellMeasure
    MrJeff
        18
    MrJeff  
       Jan 17, 2020
    想办法搞成虚拟列表 否则 DOM 太多 卡爆
    ericgui
        19
    ericgui  
       Jan 17, 2020
    @Sapp 能否给个关键词?谢谢
    qzhai
        20
    qzhai  
    OP
       Jan 17, 2020
    @ericgui 评论里 甩出来的连接基本都是 他说的原理
    M003
        21
    M003  
       Jan 17, 2020
    看过几个虚拟列表,都是需要行高度固定..
    这样才能计算出整个列表的高度,进行渲染.

    曾经也考虑过高度不一致.渲染上千条数据.

    后来放弃了.需求就是个伪需求. 还不如加个搜索框来的快.
    buhi
        22
    buhi  
       Jan 17, 2020
    https://github.com/buhichan/react-infinite-virtual-scroll
    我这个支持每行有不一样的高度, 条件是高度渲染后就不能更改(因为会缓存下来), 虽然是 react 的, 但是 vue 的话自己改下的话都能用
    qzhai
        23
    qzhai  
    OP
       Jan 17, 2020
    @buhi 哈哈哈。。我用 Angular...
    wanguorui123
        25
    wanguorui123  
       Jan 17, 2020
    虚拟列表
    lululau
        26
    lululau  
       Jan 17, 2020 via iPhone
    让用户换台 Mac pro
    GrapeCityChina
        27
    GrapeCityChina  
       Jan 17, 2020
    懒加载、双缓存机制、canvas 绘制界面... 好吧,我是在说 SpreadJS
    csgo2
        28
    csgo2  
       Jan 17, 2020
    核心思路应该就是只渲染可视区域。。。。我大概只用过前面大伙说的 react-virtualized
    YourLord
        29
    YourLord  
       Jan 17, 2020 via Android
    打死你的后台同事,直接把全表数据扔给前段也太业余了。
    xiangyuecn
        30
    xiangyuecn  
       Jan 17, 2020
    终极优化办法:干掉提需求的人
    Ritr
        31
    Ritr  
       Jan 17, 2020
    @withzhaoyu 说的对,没用的 DOM 移除掉不然会很卡
    qzhai
        32
    qzhai  
    OP
       Jan 17, 2020
    @YourLord 我们是个协同工具,复杂场景很多这个是正常的需求
    mostkia
        33
    mostkia  
       Jan 18, 2020
    可以考虑让后台分页,大量数据一次性加载到 html 是不好的做法,如果考虑到用户体验不允许有换页之类的效果,可以试试 ajax 这类,类似瀑布流的那种按需加载,都是现成的方案,挺成熟的。
    r3m
        34
    r3m  
       Jan 19, 2020 via Android
    万条数据具有多媒体数据的 table 可以先在后台缓存好每条数据对应的宽高,或者根据前端具体设备去简单在后台计算好宽高等等,最后把每一行高度数据加上每一行的 id 发送给前端。这个请求的数据量压缩前也只需要占 100kb 以内。之后前端已知宽高就可以就直接套用虚拟列表那一套,在可视范围内 lazy loading 就好了。如果要 loading 之前的可视效果更好一点后台可以顺便在其中传一些文字内容,图片颜色,视频封面颜色之类的基本信息,pinterest 上这种效果就做很好
    ccsulzf0627
        35
    ccsulzf0627  
       Jan 19, 2020
    我看老哥是用 angular 的,推荐一下 ag-grid
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1126 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 95ms · UTC 23:01 · PVG 07:01 · LAX 16:01 · JFK 19:01
    ♥ Do have faith in what you're doing.