最近在react上做一个orderBook深度图,数据接入用websocket,数据形式是第一次请求返回当前orderBook,之后每当数据有更新便会收到某个priceLevel的最新数据,大概频率是每秒30个。
做深度图的策略就是2个series的steped Area Chart
,两个series以当前价格为中心,分别代表买卖单。获取到第一组完整数据之后将数据格式化(dataArray)、排序并依次相加获得该priceLevel的总容量=>计算出当前价格(最高买入价格和最低卖出价格的中位数)=>计算出当前要显示的数据范围=>渲染.
最终效果如下
数据是real-time的,每接收到一个新的数据,更新我们的dataArray(删除、修改、新增),重新排序和加和、计算最新价格并触发渲染。
按照这样的思路做完之后,由于数据更新频率过快,数据量较大(30000+条),频繁重新渲染chart导致卡顿甚至卡死。
所以做出以下优化:
- state更新将触发页面重新渲染,我们可能需要管理很多状态,但并不是所有状态都需要用
setSate
来保存,setState
只存放必要的需要触发页面重绘的状态,以减少不必要的渲染 - 数据更新改为每0.5秒更新一次,
setState
每0.5秒执行一次 - 优化Array的增删改
setState
setState
不是同步的,但也不能严格说他是异步的。setSate
执行后不会立即更新这个state而是放入一个队列中,React.js内部会把JavaScript事件循环中的消息队列的同一个消息中的setState都进行合并以后再重新渲染组件。
但是我们也可以通过使用回调函数实现state的同步更新。
同时要注意setState
不会判断新的state是否真的发生了变化,也就是说如果我设置了相同的state值,页面同样会进行渲染,如果项目中可能会有大量类似的情况,可以用shouldComponentUpdate
这个生命周期钩子避免。shouldComponentUpdate
接受两个参数:nextProps
和nextState
1 | //在render函数调用前判断:如果前后state中Number不变, |
关于使用这个生命周期钩子的弊端,不详做讨论==>http://www.infoq.com/cn/news/2016/07/react-shouldComponentUpdate
Array的增删改
删除最后一个元素:pop
删除开头元素: shift
要删除指定元素: splice(i,1)–删除i开始1个元素,从i开始之后每一个元素都需要往前挪一个位置
依据条件删除多个元素: filter
末尾添加一个元素:push(elm)
开头添加一个元素: unshift
添加元素到指定位置: splice(i,0,elm)–i位置开始删除0个元素,在该位置添加elm
若需要更高效率的增删元素的话,建议使用linkList
数组的原生sort排序方法是没有规定内部使用什么排序算法的,不同的浏览器内核有不同的实现,chrome,ie:快排, firfox:归并。
应根据项目情况选择使用原生排序还是自行封装
定时器
react定时器要在componentDidMount生命周期方法挂上,然后在componentWillUnmount生命周期方法清除。
1 | componentDidMount() { |