如何在瀏覽器不崩潰的情況下過濾 200 萬行資料?
最近我分配到了一個非常有趣的任務:在前端顯示 1GB 檔案和 200 萬行資料,並實現過濾,在這篇文章中,我將分享我是如何完成這個任務的。
背景
我曾經建立了一個簡單的 React 應用程式。這個應用程式從伺服器載入一些資料,並呈現在幾個表格中。在成功演示了 React 應用程式後,客戶授權我訪問生產資料。然後,有趣的事情發生了。當我將應用程式從開發 API 連線到生產環境並重新載入頁面時,看到了類似“顯示此網頁時出現問題”的錯誤。經過除錯,我發現生產伺服器的 JSON 檔案大小約為 500MB(而不是從開發伺服器的 2 到 5 MB)。
最新的需求是:
1.JSON 檔案最大可達到 1 GB。
2. 後端不會進行分頁——只能接受這個事實。
首先,我嘗試了 react virtualized,一個 React 元件,可以通過虛擬渲染有效地渲染 大型列表 。
但幾天後又出現了新的需求:
3.“標準的瀏覽器搜尋(Ctrl/Cmd + F)功能無法正常工作,必須修復這個問題!”
虛擬列表背後的主要思想是隻渲染可見的內容。因此,如果使用者在搜尋框中輸入一些東西,那麼瀏覽器只會搜尋虛擬列表的可見部分。
下圖演示了瀏覽器是如何搜尋虛擬列表的。請注意,滾動後出現的記錄(虛擬列表進行了重新渲染)沒有高亮顯示,儘管包含了要搜尋的值“@”。
搜尋框
我決定建立一個具有類似預設瀏覽器搜尋功能的自定義搜尋框,但可以搜尋所有的 200 萬條記錄。
對大量資料進行過濾操作會導致“堆記憶體不足”。截至 2018 年 4 月,我沒有找到任何提供內建搜尋 / 過濾功能的 React 虛擬列表實現。
經過幾個小時的谷歌搜尋和在 Stack Overflow 網站上提問之後,我想到了 Web Worker,並使用了 Simple Web Worker 庫 。這個方法的主要思想是將一個大陣列拆分成更小的部分,並使用 Web Worker 非同步處理每個部分。
找到最佳的塊長度是很有必要的。塊的長度越短搜尋速度就越慢,但長度越長,在低配置裝置上出現“堆記憶體不足”的可能性就越大。在我的例子中,根據實驗結果,3000 是最佳長度。
華麗制勝
下圖演示了自定義搜尋框。在發生滾動後,高亮顯示不會消失,使用者可以通過箭頭按鍵在行和表之間導航。是的,過濾資料確實需要一些時間,但它可以處理比之前更多的資訊。為簡單起見,陣列只包含了 9000 個項,但可以隨意新增,不過過濾時間也會隨之增加(過濾 200 萬行可能需要 5-7 分鐘)。
這種方法幫助我解決了幾個問題:
- 過濾大量資料而不會導致瀏覽器崩潰。在我的例子中,檔案的最大大小約為 1GB,最多有約 200 萬行資料。
- 建立一個搜尋框,提供與原生瀏覽器搜尋類似的 UX,可以搜尋所有 200 萬行資料。
你可以在這裡找到應用程式的原始碼:
https://github.com/uptechteam/react-filter-demo
演示: https://uptechteam.github.io/react-filter-demo/
解決方案簡短描述
這個 React 應用程式包含 3 個元件:
-
App.js——應用程式的主要元件;
-
SearchBox.js——實現搜尋框功能的元件,使用箭頭按鍵導航搜尋結果;
-
TablesViews.js——渲染結果表格的元件,它演示瞭如何在表格之間實現 SearchBox 導航。
英文原文:
更多內容,請關注前端之巔。