大數據項目根據用戶輸入代碼查詢數據,用戶的代碼不可控(好比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