在过去的几周里,我对不同的图表库进行了大量的研究和实验--特别是高海图和Chart.js --试图从它们中挤出最好的性能,结果却让我失望。
可突变性与不可变性:
首先,我决定放弃Redux,因为在数据/状态部分,我将所有数据点存储为[{x: sometimestamp, y: somenumber}]格式的数组中的对象
我放弃了Redux作为我的状态容器,因为为每个插入创建一个副本,在很大程度上不能很好地执行。想象一下复制一个由100000个对象组成的数组,而您想要的只是在数组的末尾推送一个新的数据池对象。
另外,当到达(用户定义的) maxCount时,我正在移动数组中的第一个项,同时将新项推到末尾。这样,图表就“移动”了。
由于Redux以其不变的方式做事,并没有完全削减它,所以我选择使用MobX。数据对象的可变状态正在按其应有的方式被移动和推送,所以现在我唯一的工作是尝试在每次新数据到达时(在实际代码中大约每秒钟)将其呈现到图表组件中。
用例
所以..。假设您每秒存储一个新的数据点,24小时= 86400个数据点。这是极端的情况,通常我不需要超过3600点(最新的一小时)在一个移动的实时图表。有时,虽然它可以帮助我多系列(通常2-5,但不超过10,这将意味着36000分)。
通常,我会同时在屏幕上显示2-4个图表,每个图表都支持上面提到的多个系列,每隔一秒就会更新一次,当新的数据到达时。
从基准点观察到的
现在,我看到了非常高的CPU利用率,当我只想显示一个低于2000点的图表时。即使是20个百分点,这个百分比似乎有点过高,即使动画是禁用的。
的反应方式,vs ref + lib内部API /
很长一段时间以来,它一直困扰着我,处理图表的反应方式是将数据作为支柱传递。到目前为止一切顺利。我的问题是,这个数据支柱只会被react.render识别为“更改”,因此会被重新命名--如果您复制了整个数据点数组。这对于小型数组很好,但对数千个对象则不然。
我试着做个回购来证明这一点:
ChartJ(React)版本:https://github.com/BruceL33t/mutable-high-performance-real-time-charts-in-react/tree/chartjs-reactish
因此,通过使用MobX和可变数据,我找到了一种解决方案,可以避免每次更新都要复制数据点。我能看到的唯一真正的解决方案是对图表库进行参考,并直接调用它的内部api addPoint(point) (High图表)或datasets[0].data (chartjs),然后直接对图表进行重绘()/ update()。这样,组件就不会在初始呈现之后使用react的呈现功能。
我本以为这会快得多,因为我们“离金属更近了”,并且直接变异图表数据,但是我没有看到使用ref真正的性能改进。
Chartjs版本:https://github.com/BruceL33t/mutable-high-performance-real-time-charts-in-react/tree/master
高级图表版本:https://github.com/BruceL33t/mutable-high-performance-real-time-charts-in-react/tree/highcharts
尝试上面的示例
在index.js中,尝试将间隔从1000 In降低到100 in (第103行),并将第90行的maxSize设置为Sensor(2000),并在任务管理器打开的情况下运行,所有其他选项卡关闭并监视铬的cpu使用情况。如您所见,当我们接近2000数据点时,cpu利用率接近60%。再说一遍-这是没有动画的。随着动画,它开始在40左右,并从那里上升。
任何提高性能的想法(较低的CPU使用率)
cpu每秒钟在画布上移动点的工作量很大,还是我做错了什么?你知道有其他图表库处理实时图表,每秒钟数千点吗?通常,您如何处理可更改的数据点数组(来自MobX或其他方面),并在一个图表中呈现它?任何良好的做法时,采取“脱离电网”的反应,以寻找更多的“裸金属”的力量。除了使用参考资料或遵循好的模式之外,还有其他方法吗?
编辑:
虽然我还没有测试过它们,但是从外观上看,下面的图表看起来比我到目前为止遇到的其他图表库的性能要好得多。
我现在要对它们进行测试,并在我试用它们之后进行更新。
发布于 2018-03-01 23:59:59
每次移动数组时,都需要移动每个项目的位置,因此最好复制整个数组。要解决这个瓶颈,您可以做几件事。第一是接受较少的数据点。你的用户的屏幕比你想要渲染的点的宽度要小,所以除非你有一个非常密集的图形和很多线,你可能已经可以用更少的数据点在视觉上逃脱。
问题仍然是一样的,尽管如此,你将不得不做更多的欺骗。您可以做的事情是找到一种方法将索引提供给图表库,这样您就可以追加数组,并告诉图表只呈现从索引开始,等于附加到数组中的项的数量。图表仍然需要重新划分每一个点,但我们已经到了。
最好的解决方案是跳过最后一个技巧,找到一个图表库,它可以动态呈现新点,或者当给定一个新的点数组时,它只呈现新点,并将这些新点呈现到旧点的右侧,而不是重新复制其余的点。为了让它在视觉上看上去,你需要将图表放到水平滚动视图中,然后禁用滚动,并将其粘在右边。不过,你必须自己做出传奇和衡量标准。
希望有人能为你找到更好的解决方案,哈哈,祝你好运。
https://stackoverflow.com/questions/49053197
复制相似问题