程序是这样的:
问题有这些:
目前我选择的是 tauri+vite+react+highchart(highstock).
我调研的每一个绘图库都吹榜他的性能, 包括上面选择的 highstock.
后端性能没有问题, 交互时后端单独发送数据, 前端使用 debounce.
但是性能却非常糟糕.
1
paopjian 7 天前 1
好家伙,每秒 96*3 的数据还要时时绘图?这不现实吧,前端折线图这种每次改数据是要重新计算的,你这算得过来吗
|
2
miloooz 7 天前 2
echarts 的大数据量绘图还可以啊 。
通道数据在绘图时 是追加到原有数据还是覆盖了所有数据额,覆盖可能会有性能问题,追加的话会好很多。 |
3
miloooz 7 天前
https://echarts.apache.org/zh/api.html#echartsInstance.setOption
不过我没做过这么大数据量的测试,你可以试试看哈 |
4
shadowyue 7 天前
你说的性能糟糕具体指什么现象
|
5
shadowyue 7 天前 1
你不如直接丢一份测试数据出来,还有设计图
|
6
crazyBlack 7 天前 1
首先肯定是一起发好,减少连接数
你这数据量到底有多大,能碰到绘图库的性能上限,你先确认一下是数据存的太大内存顶不住了,还是点太多绘制上去有问题,如果是绘制的问题正常的库都会有给数据抽稀的方法,过大的数据直接绘制上去意义不大,我盲猜是数据量过大存不住了,你可以研究一下接一层 bff 做数据整合和抽稀,或者交给后端做 然后前后端分离和追求性能不冲突,如果你觉得是交给客户端的计算量过大可以试试尽量把计算放在 worker 里或者考虑 next 或者 remix 这样的服务端渲染框架 |
7
crazyBlack 7 天前
我才看到技术栈里还有个 tauri ,next 或者 remix 当我没说,生产敢用这东西的都是个猛人,打扰了
|
8
andyskaura 7 天前 1
1.都差不多,但只要前端的主线程没出现堵塞,一起发送更好。websocket 会自己分片,ipc (我不知道你前端的什么 ipc ,只说 electron 的 ipc )大数据会有一定延迟( 4k 的 bmp 会有 200ms 左右延迟),但预估你数据量还没那么大。
2.别用 svg ,用 canvas ,绘图的渲染性能都没什么压力的,毕竟都只是 2d 的。我猜测问题可能出在数据处理上,可以用帧循环来将 96 个数据排序提交,减小并发。用 woker 或者 wasm 来优化处理,无论怎样,千万别让主线程卡住了。 3.感觉前后端分不分离和性能没啥联系。 最好还是把问题现象描述的清楚一点,主要不好分析出现在堵在哪儿了 |
9
chairuosen 7 天前 1
不用 UI 框架的内置 state ,直接调用绘图框架的更新方法更新,绘图框架最好是 canvas 的,这样就只有数据计算过程,没有 vdom 的更新
|
10
lurenjiaMAX OP @shadowyue 好的 我后面收拾一下代码 做一个最小可运行实例分享出来
|
11
thulof 7 天前 1
你是不是每次都全量重绘的…… 只追加 delta 就好了吧
|
12
sgiyy 7 天前 1
你要把你的效果图和具体数据量大小放出来才好评估
|
14
lurenjiaMAX OP @sgiyy 效果图是这样的 ![图片]( )
|
15
Moierby 7 天前 1
我做过一个页面 30 个折线和柱状图的需求,直接一次性请求过来一把梭,用的 echarts ,基本没有明显卡顿。不过我的绘图数据比较小,每张 chart 上也就几十个节点。
现在流行的 chart 库都是用 canvas 实现的,每次绘制都是清理完之前的图层,重算重绘,也就是图表渲染这一步你基本没有什么可优化的空间。 你看一下你的瓶颈在哪,针对性的优化: 如果数据请求太慢,你就不要一个接口一次性返回所有 data ; 如果单个 chart 数据节点太多,一次性绘制 96 个太占资源,你就判断哪些出现在当前 viewport 才绘制哪个 |
16
lurenjiaMAX OP @crazyBlack 数据量没有多少 就是每隔一秒获取一次最新的数据 增量更新
|
17
MRG0 7 天前 1
一次性显示 96 个,这眼睛看的过来吗
|
18
lurenjiaMAX OP @Moierby 这是个好主意! 我测试只显示 4 个图的话是没有多大压力的
|
19
horizon 7 天前 1
先 measure ,再优化
|
20
moooooooo 7 天前 1
为什么要一次显示 96 个....一点交互都不讲究的?
|
21
lurenjiaMAX OP |
22
msmmbl 7 天前 2
之前做过 120 个摄像头的缩略图+状态数据,但是不像楼主要秒级的,用的是 websocket ,大概有:
1. 判断哪些图像在浏览器滚动条外面,看不见的不刷新。 2. 一个批次一个批次的请求。比如先一次请求 10 个画面,然后画到页面上,观察用了多久时间,根据时间动态调整下一个批次的数量,尽量让每个预览窗口雨露均沾。 3. 状态用了增量数据,每次只发送上次和这次的改变。 |
23
crazyBlack 7 天前
@lurenjiaMAX 这个链接是个空项目,你看看哪里出了问题,上面只渲染当前可见是个好方法,试试 react-window
|
24
sampeng 7 天前
所以我特别好奇 grafana 如何做到的。几乎页面不带卡的
|
25
lurenjiaMAX OP |
26
lurenjiaMAX OP @miloooz 是的 我就是用的追加数据. 后面我也试一下 echarts
|
27
lurenjiaMAX OP @chairuosen #9 我是参考 https://www.npmjs.com/package/highcharts-react-official#optimal-way-to-update 这个绘图库提到的最优方式来更新的
|
28
okakuyang 7 天前
用 canvas 不是随便画,都是些 2d 的简单东西。而且不需要同屏显示,看到那些就显示那些。
|
29
ty29022 7 天前 via iPhone
重采样呗 有啥纠结的
|
30
sgiyy 7 天前
@lurenjiaMAX #14 总的需求就是 96 个图表,不过每个图表的数据量不大。
回答你的问题: 1. 数据量不大的话,一个接口发送最好。 2. 流行的图表库一般都没问题,我这边最常用的是 Echarts 。 3. 这种架构没问题 其他:另外一个最需要注意的是图表的数量以及重绘的压力,js 有个 IntersectionObserver 的 API 可以判断元素是否在可视区域,可以封装个 hook ,不在可视范围内就不更新图表,这样页面性能压力会大大减小。 |
31
214L 7 天前
我遇到 echarts 等库解决不了的图表性能问题的时候,采用的解决方案是自己写了一个。单纯的 canvas 绘制图表和缩放,更新,交互逻辑,最终表现流畅。
数据量大概是 600 条线,每条 1300 个点? 不过我的图表是我们这个项目的核心模块,所以有时间去打磨。 |
32
qping 7 天前 via iPhone
你这么大的图,一屏幕也显示不了几个。后台数据可以接收,但是不用都渲染,监听下 scroll ,只刷新可见区域
|
33
ccdjh 7 天前
就是前端的问题。
1 ,你这小数据。强迫症的话,就服务器压缩一下。 2 ,市面上的都可以,根本上应该是 react 和 vue 这些机制是会重刷或遍历一次整个页面,所有会导致性能下降。你前端接收数据,如果坚持使用上面的框架,就局部渲染。 3 ,技术都没错。技术不到位。 实际就是搞个 1 秒心跳一下的客户端。技术压力在前端了。一般会写但不太了解原理的前端导致的。-_- 自己画几个,highchart 钱省了,性能也上来了。就是前端工资价格贵了。 |
34
thulof 6 天前
用虚拟列表吧,react-window 了解一下
|