最近在給公司的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 給我留言。