最近在给公司的grid组件进行性能测试和改善,其中很是重要的一个点就是grid加载100k级别的数据时,居然出现的情况是,渲染不是问题,初始化的时候遍历数据才是问题。git
之因此渲染不是问题,是由于组件采用了特殊的渲染方式,它并无把全部数据一次性渲染到可视区域中,而是经过滚动条的计算,找出对应应该显示的那些条目,仅仅渲染了部分数据,因此加入的DOM节点就少到可怜,天然快不少。github
如今的问题,彻底放在了初始化的时候,要对这么大的数据量进行遍历,而且对每个cell的数据执行format操做,可想而知,在不一样的机器上,性能天然受到很大的影响。web
我所采用的解决方案,是利用HTML5的新特性web worker来解决。worker的应用场景原本就是在backend进行大规模或持久化计算,用在这里正好。之因此在遍历的时候被卡住,就是由于咱们遍历的时候,占用js主线程,致使其余程序没法进行。就算使用Promise优化,也会由于排队形成排队以后的操做被卡住。worker是在主线程以外另外开了一个线程,和主线程彻底隔离,所以在内存分配上和进程占用上都不同,worker线程中的程序执行彻底不影响主线程中的执行。所以,将主线程中一个可能须要用到500+ms的计算移到另一个线程中,主线程程序能够无缝继续执行,经过Promise来接收worker线程返回的数据,作到无缝对接。api
下面来看具体实现:promise
1 获取quicker-worker源码函数
quicker-worker是我在结合了本身对其余开发者的代码阅读以后撰写的两个函数,站在前人的肩膀上倍感愉悦~性能
你能够经过 https://github.com/tangshuang... 获取源码。测试
2 使用run函数优化
在quicker-worker的readme中我详细阐述了它的使用方法,这里就不具体介绍,为了解决上面的grid的问题,咱们使用run函数来实现对grid组件的改造。ui
在grid组件中,有一个遍历,在遍历过程当中,对每个元素进行format。咱们以下进行操做:
// .. 其余初始化 run(`function(data, formatter) { data.forEach(function(item) { formatter(item) }) return data }`, [data, formatter]) .then(data => { this.set(data) // .. 后续操做 })
就是这么简单,没有任何拖泥带水的操做,就像一个promise同样。
使用quicker-worker还能够实现很是漂亮的后台监控,每隔一段时间去查询数据是否变化。
let wk = create(`function(data, compare) { return $xhr.get('/api/books').then(function(res) { if (compare(data, res)) return res }) }`, { interval: 60*1000, xhr: true, }) wk.invoke([data, compare]).then(newdata => { if (newdata) updateData(newdata) })
就是这么简单。若是你有什么疑问,能够在github上给我提issue。关注个人博客 www.tangshuang.net 给我留言。