瀏覽器內 SQLite:把查詢下推到 Worker 的 WASM heap
當前端要處理的列數大到「全部展開成 JS 物件就爆掉」時,一種解法是讓後端直接產出
.sqlite檔,前端在 Worker 裡用 sql.js(SQLite 編成 WebAssembly)打開它,把分頁、排序、搜尋、count 全部下推成 SQL。
心智模型:SQLite 是唯一真相,前端 store 降級成單頁快取
- 讀:完全走 SQL,
SELECT … ORDER BY … LIMIT 50 OFFSET 12000;錯誤也是 SQL,把 errors 表 join 進當前頁的範圍 - 寫:write-through——store 先更新讓 UI 不卡,再送訊息給 Worker 執行
UPDATE,真正被送回後端的是 SQLite 的內容 - 顯示:cell 渲染、欄位設定、i18n 還是原本的 React 那套
store 只裝當前這一頁,所以「第幾列」的語意會改變:一般模式要透過 sortedIndices[pageOffset + row.index] 換算,下推模式下 row.index 直接就是答案。
為什麼省記憶體(兩個原因,都不是「搬到 Worker」本身)
- 儲存格式換了 — 同一列從 JS 物件圖變成 SQLite 的緊湊 bytes → JS 物件比原始資料胖好幾倍
- 主執行緒的 working set 從 O(N) 變成 O(1) — 只持有當前 50 列
搬到 Worker 本身不省記憶體(見 Worker 與分頁共用同一份記憶體配額),它換到的是不阻塞主執行緒。
天花板
sql.js 的預設 VFS 是純記憶體的,整份 DB 必須完整存在 WASM heap,所以常駐仍是 O(N);要真正降到 O(page cache) 得換 VFS → OPFS sync access handle 讓 SQLite 能在瀏覽器只讀用得到的 page。峰值問題見 記憶體峰值倍率:OOM 發生在轉換的瞬間。