大数据项目根据用户输入代码查询数据,用户的代码不可控(好比select from db limit 5000),有可能一页需求要求展现100行5000列数据。因为是用户代码实时查询的数据,后端不可能将全部查询结果都存储。所以,查询的结果是实时的、全量的,分页和排序都须要前端去实现。前端
刚开始的接手项目的时候彻底不能展现十万级的数量,chrome标签页直接崩溃。这个在分析了需求,展现数据不须要响应式后,用了Object.freeze()后就能够勉强展现十万级数据。虽然仍是卡顿,可是需求已经实现。(值得注意的是Object.freeze()并非深度冻结,实际应用中对象要进行递归操做。)vue
下面图展现的是100行乘以一千列,在左右拖拽0-150列。目前也对超过两百列的数据进行横向的懒加载操做,实现原理时监听scroll事件滚动到末尾时截取对应下一组数据,而后将滚动条恢复到头部。能够从gif中明显感受到这个过程是滚动条恢复到原状之间耗时比较长。并且当用户想要看前一组数据的最后一项和后一组数据的前一项时,js就要不停地作截取数据的操做从新渲染,开销很是大。git
利用chrome devtool performance进行性能分析。(进行性能分析时使用隐身模式避免chrome插件对结果分析形成误差)github
因为后端返回的数据一组表头和内容分开的数组,而开源element-ui的vue组件都是以key:value的形式,大量数据状况下仅仅是将数组转化为key:value的形式就花费掉几百毫秒的时间。开源组件能解决的是通用状况,这种状况下为了尽可能减小开销重写适用于业务的table组件仍是颇有必要的。chrome
//后端返回的格式 data = [ columnName: ['col1', 'col2', ……], columns: [ ['1', '2', ……], ['1', '2', ……], …… ] ] // 开源组件须要的格式 data = [ { col1: '1', col2: '2', …… }, { col1: '1', col2: '2', …… } ]
后端返回的数据量有可能高达百万级,尽管前端进行分页仍是有可能要展现到数量达十万。其中行最多每页只展现100条,可是列由ide用户执行的代码决定,这里主要影响性能的是列数。列数有可能为1000条,模拟横向懒加载,将拿回来的数组截取部分展现,减小页面上的dom节点。可是目前模拟懒加载的方式用户体验很差。element-ui
- 但这种方式也是很是不友好,每次滚动到最后要去检测用户是否按着鼠标有没有抬起,防止触发屡次数据从新渲染。由于这种状况下,用户拖一次只能加载一组新数据,滚动条便回到了中间位置,若是用户须要看到最后一组数据就要屡次操做。正常的懒加载应该是有一条适应高度的滚动条拖拽,无缝链接。 - 懒加载方式常见的有: 1. 淘宝一屏用元素占据必定的高度,而后再去拉图片数据。滚动条便适应高度的拖动距离。但这种方式仍是须要元素占位,淘宝一页的数据量其实不算大,由于它结合了分页。 2. 掘金沸点的无限加载:掘金的方式是监听到底部时,再去拉响应的数据追加,滚动条会自适应滚到相对应的地方。可是掘金这种懒加载一直加载数据没有截取掉旧数据,因此滚动条距离也是一直适应数据的。尝试将掘金沸点一直拖动到2000条,网页已经开始有点卡顿。而在ide项目中,两千条数据算是少许数据。 - 启发于[https://github.com/tangbc/vue-virtual-scroll-list](vue-virtual-scroll-list),利用了padding值模拟了淘宝固定高度,不须要元素占位,模拟出所有数据量的滚动条纵向滚动距离,拖动时彻底无感知数据的从新渲染。目前vue-virtual-scroll-list只支持纵向,但稍微改造下就能用在ide项目的横向懒加载。(改造后以下图,gif软件录制时稍微有点卡顿感)
拖动几百条数据截取的performance在FPS图表中已经没有最初的红标,没有Forced reflow,每帧的rendering也由rAF控制在16.7ms之内,js内存占用也从161mb-325mb,下降到157mb-196mb。后端
复用性:配置参数的方式去差别化体现,参数的可配置性提升了组件的复用率和灵活性。
可维护性:组件化后,组件内部的逻辑只对组件负责,外部的逻辑只经过配置参数适配,提升了代码的逻辑清晰度,能够快速定位代码出现问题的地方。数组
这个组件设计时对外提供toLeft,toRight,onScroll事件,分别是滑动过程当中到了头、尾,及滑动过程的回调。提供了offset,remain,bench参数表示刚渲染时的误差,显示的列数,及保留多少列在实际dom中。dom
之前没有想过js也会承受那么大的压力,一点点优化都能显著减轻内存。在写代码时要特别关注高频事件的触发,一切的优化方向就是在实现功能的前提下减小从新渲染的发生。ide