假设,页面需要在一个表格里渲染 几万条 数据。在不分页的情况下有什么好的优化方案来保证页面的流畅度。
(可能例子有些极端)
1
Sapp 2020-01-17 10:16:22 +08:00
虚拟列表,简单来说就是 1w 条列表,每次只渲染一部分,之后滚动的时候实时渲染出新的来模拟滚动,这样 dom 实际就是几十条的样子,网上有很多现成的方案
|
2
shijianit 2020-01-17 10:17:08 +08:00
在滚动事件里面做判断,屏幕外面的数据,元素就删除,只保留高度
|
3
zhuzhibin 2020-01-17 10:19:43 +08:00 via iPhone
貌似都在说 lazy load ?
|
4
fancy111 2020-01-17 10:20:15 +08:00
一个表里面几万条? 能看得完吗?为何不分批
|
6
Mozshaw 2020-01-17 10:20:25 +08:00
关键词:virtual scroll
可参考 https://github.com/tangbc/vue-virtual-scroll-list |
7
zaynex 2020-01-17 10:24:44 +08:00
@qzhai 假设高度不一致的话,这种虚拟列表应该是没法用了。嵌套的数据结构可以利用 web worker 在里面转换成平铺的数组,每次增量渲染若干个节点。
|
9
momocraft 2020-01-17 10:36:15 +08:00
高度不一致时虚拟列表可能会有什么问题?比如滚动条不准?
|
10
zhw2590582 2020-01-17 10:41:05 +08:00
之前也遇到过这个问题,用了这个: https://github.com/bvaughn/react-virtualized
|
11
qzhai OP @momocraft 虚拟列表是通过高度来计算出当前 可视区域内的数据的。如果高度不一致就无法计算可视区域内究竟有多少数据以及是什么数据,也就不能来删除或者渲染数据。
|
12
zhw2590582 2020-01-17 10:43:09 +08:00
不过 react-virtualized 的默认是高度要一致,假如高度不一致需要自己提前计算出来再传值到组件里。
|
13
lovedebug 2020-01-17 10:44:58 +08:00
|
15
diveIntoWork 2020-01-17 11:06:59 +08:00
双缓冲
|
16
linghucq1 2020-01-17 11:20:47 +08:00
|
17
ccraohng 2020-01-17 11:26:59 +08:00 via Android
不是有支持动态高度的么,类似 CellMeasure
|
18
MrJeff 2020-01-17 11:28:00 +08:00
想办法搞成虚拟列表 否则 DOM 太多 卡爆
|
21
M003 2020-01-17 11:35:32 +08:00
看过几个虚拟列表,都是需要行高度固定..
这样才能计算出整个列表的高度,进行渲染. 曾经也考虑过高度不一致.渲染上千条数据. 后来放弃了.需求就是个伪需求. 还不如加个搜索框来的快. |
22
buhi 2020-01-17 11:35:57 +08:00
https://github.com/buhichan/react-infinite-virtual-scroll
我这个支持每行有不一样的高度, 条件是高度渲染后就不能更改(因为会缓存下来), 虽然是 react 的, 但是 vue 的话自己改下的话都能用 |
24
w292614191 2020-01-17 14:11:08 +08:00
|
25
wanguorui123 2020-01-17 17:25:06 +08:00
虚拟列表
|
26
lululau 2020-01-17 17:28:25 +08:00 via iPhone
让用户换台 Mac pro
|
27
GrapeCityChina 2020-01-17 17:32:47 +08:00
懒加载、双缓存机制、canvas 绘制界面... 好吧,我是在说 SpreadJS
|
28
withzhaoyu 2020-01-17 17:47:21 +08:00
核心思路应该就是只渲染可视区域。。。。我大概只用过前面大伙说的 react-virtualized
|
29
YourLord 2020-01-17 17:50:33 +08:00 via Android
打死你的后台同事,直接把全表数据扔给前段也太业余了。
|
30
xiangyuecn 2020-01-17 17:52:38 +08:00
终极优化办法:干掉提需求的人
|
31
Ritr 2020-01-17 17:53:39 +08:00
@withzhaoyu 说的对,没用的 DOM 移除掉不然会很卡
|
33
mostkia 2020-01-18 13:34:11 +08:00
可以考虑让后台分页,大量数据一次性加载到 html 是不好的做法,如果考虑到用户体验不允许有换页之类的效果,可以试试 ajax 这类,类似瀑布流的那种按需加载,都是现成的方案,挺成熟的。
|
34
r3m 2020-01-19 06:14:13 +08:00 via Android
万条数据具有多媒体数据的 table 可以先在后台缓存好每条数据对应的宽高,或者根据前端具体设备去简单在后台计算好宽高等等,最后把每一行高度数据加上每一行的 id 发送给前端。这个请求的数据量压缩前也只需要占 100kb 以内。之后前端已知宽高就可以就直接套用虚拟列表那一套,在可视范围内 lazy loading 就好了。如果要 loading 之前的可视效果更好一点后台可以顺便在其中传一些文字内容,图片颜色,视频封面颜色之类的基本信息,pinterest 上这种效果就做很好
|
35
ccsulzf0627 2020-01-19 09:15:36 +08:00
我看老哥是用 angular 的,推荐一下 ag-grid
|