flex bison解析json文件_浏览器处理2500MB JSON文件的解析与绘图问题(实践分享,非战斗人员请忽略)...

最近在做一个浏览器画数据图的任务。

任务其实很简单,浏览器通过ajax请求拿到服务端已经生成好的json文件,然后在前端浏览器绘制相应的折线图,饼状图等。

3a33828bc4f7c7586f3e82c53b0cebc9.png
很丑陋的dataflow

起初我的做法

leader给我这个任务的时候,我想这不很简单吗。好吧俩天交差,先给我一个大概的json数据结构,我来造个假数据。

技术栈里面使用vuejs,因为要根据不同的ID 过滤数据重新绘图,想想虽然原生Javascript也能搞定,但毕竟是内部一个演示项目,就杀鸡用一次牛刀吧。

敲敲敲。。。 好了,代码完成。上dev环境

上dev环境之后

上线之后,运维人员说:老铁,你这个不work呀?

我嘀咕:不work,是不是你打开的方式不对?

我自己打开浏览器看了一下,确实很长时间页面都是空白的,然后运行2、3分钟之后页面崩溃。纳尼?老子的代码居然这么脆弱?

我打开Chrome dev tool看一下千里之堤究竟溃于哪里。原来真实的json文件尺寸大概是2.5GB,我了个乖乖。有木有搞错呀?你们这些运维人员让浏览器去解析一个2.5GB的json文件,怎么可能完成吗?JSON.parse表示臣妾做不到呀。

运维人员:我不管,过俩天大老板就要看数据图,你看着办吧。

我:。。。

e279dc1221bcc3761cba8f0c6b23346c.png

真实JSON文件数据图如下

239f9b91f79264a12495040e03141f87.png

你们这是为难傲天呀!!

我想的第一个解决办法就是:服务端流式读取大文件=>解析=>计算绘图所需的数据=>结果数据丢给前端

但是有个问题,计算绘图所需的数据这一步我都在前端实现好了呀,难道要把这部分代码搬到server来吗?而且就算这样,也只是把2.5GB的数据变成100MB的结果数据,这个结果数据还是很大呀,浏览器能解析这么大的json文件吗?

不行应该用一种更优雅的方式解决!

首先我知道一点就是,这个任务现在的瓶颈就是:浏览器无法一次解析这么大的JSON文件。内存其实都不是问题,Chrome现在一个page上GB的内存使用都是可以的。

要不然在浏览器与文件服务端之间加一个中间组件,这个中间组件将JSON拆分成一条条小的JSON数据,浏览器将这些小的JSON数据依次解析然后放入内存中。

然后这个中间组件就用一个websocket服务来实现。

0c96fcfe2d70fe974bd67ac9857d0f19.png
依然很丑陋的dataflow设计图

进一步优化

考虑到JSON文件中有的字段数据并用不到,这里我在websocket服务做了一层过滤将用不到的字段丢弃,又为前端节省了一大笔内存开销。

果然这个方案可以了!json数据终于可以传输到浏览器了,而且这个方案中浏览器每次解析一小段json文件,不存在JSON.parse内存溢出的问题了。

附一张websocket传递拆分JSON的图片:

b8cdf07078f99702d4bdce771d500c2b.png

然鹅新的问题又来了!

合并的JSON数据已经变成Javascript对象了,准备挂载到vuejs的data上,但是一挂载崩溃!

卧槽,原来是vuejs需要给data数据设置get set等方法,为了UI及时响应数据的变化。然鹅我们的数据有329万条

eb779f0fdceb02cc4dd5786da9ffaa87.png

vuejs在为这么多数据设置get set的时候,崩溃了!

810cede9b383b3245b2524fc6581401f.png

找到了root cause,傲天自然知道该怎么做了。我不把这个数据挂载到vuejs中不就可以了,我把这些数据挂载到window对象上,然后vuejs组件画图的时候从window对象里面取值,完美解决,bingo!

总结

其实主要就是加了一个websocket服务来中转一下巨大JSON文件,并且将JSON文件拆分成小的JSON片段。中间用到了一些开源的技术,顺便分享给大家。

还有我想这个websocket服务还可以做成一个共用的中间件,岂不是更棒。

用到的开源项目:

  1. ws 非常简单又贼他么快的websocket服务,为了nodejs而生
  2. JSONStream 流水式解析巨大json文件

关于霸都丶傲天

  • Github : Github.com/AJLoveChina
  • zhihu : zhihu.com/people/AJLoveChina
  • 纪念日:爱情表白结婚纪念日网站

fdecedc116116c3df6746c789e120944.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值