Web APIs 實戰:
Web Workers、IndexedDB、Intersection Observer
瀏覽器原生 API 的三大場景 — 背景執行緒、離線儲存、懶載入 — 不依賴框架的原生能力
Section 1:瀏覽器比你想像的更強大
現代瀏覽器早就不只是「渲染 HTML 的工具」了。Web 標準在過去十年間發展出大量強大的原生 API,讓你不需要依賴任何第三方框架,就能在瀏覽器中做到背景計算、大量資料儲存、高效能 DOM 監聽、頁面間通訊、甚至加密操作。
Web Workers
在背景執行緒跑 CPU 密集計算,不阻塞主執行緒 UI 渲染
IndexedDB
瀏覽器端的 NoSQL 資料庫,支援 GB 級離線儲存與索引查詢
Intersection Observer
高效偵測元素是否在視口中,實作懶載入與無限捲動
ResizeObserver
偵測元素大小變化,取代 window.resize 監聽
Page Visibility API
偵測用戶是否切換到其他分頁或最小化視窗
Web Crypto API
瀏覽器端 AES/RSA 加密、SHA hash、UUID 生成
為什麼要學原生 Web API?
React、Vue 等框架的底層都是建立在這些 Web API 上的。當你理解底層,不只是能在框架之外解決問題,也能在框架中寫出更高效的程式碼。例如,很多開發者用第三方套件做懶載入,但 Intersection Observer 原生就能做到,而且效能更好、bundle 更小。
Section 2:Web Workers — 別讓計算凍結 UI
JavaScript 是單執行緒的語言,主執行緒(Main Thread)同時負責執行 JavaScript、處理用戶事件、以及渲染畫面(Layout、Paint)。一旦有耗時的計算佔用主執行緒,用戶就會看到 UI 凍結——滾不動、點不了、動畫卡住。Web Workers 讓你開一個背景執行緒,把計算工作交給它,主執行緒繼續保持流暢。
問題 vs 解法
Web Worker 通訊模型
在 React 中使用 Web Worker(with Comlink,更簡單)
原生 Web Worker API 用 postMessage / onmessage 通訊,寫起來像在用事件系統,不夠直覺。Comlink 是 Google 開發的輕量包裝庫,讓你像呼叫普通 async function 一樣呼叫 Worker 中的函式。
適合交給 Worker 的任務
- • 大量資料排序、過濾、轉換
- • 圖片處理(濾鏡、壓縮、像素操作)
- • PDF 生成、報表計算
- • 機器學習模型推論(TensorFlow.js)
- • 加密解密(也可用 Web Crypto API)
Worker 的限制
- • 無法存取 DOM(不能操作頁面元素)
- • 無法存取 window 物件
- • 通訊資料會被複製(非共享記憶體)
- • 傳遞大資料有效能成本(可用 Transferable Objects 解決)
- • 每個 Worker 是獨立的 JS 環境
Section 3:Intersection Observer — 懶載入與無限捲動
Intersection Observer API 讓你非同步地觀察目標元素與其祖先或視口(Viewport)的交叉狀態。白話說:它能告訴你「這個元素現在有沒有在畫面上」。這個 API 是瀏覽器在「後台」幫你計算的,比監聽 scroll 事件效能好得多。
傳統做法 vs Intersection Observer
React Hook 封裝
Section 4:IndexedDB — 瀏覽器的本地資料庫
IndexedDB 是瀏覽器內建的 NoSQL 物件資料庫,支援事務(Transaction)、索引查詢、以及儲存各種 JavaScript 物件(包含 Blob、ArrayBuffer)。相比 localStorage,它的儲存上限大得多(通常數百 MB 到 GB 級),且操作是非同步的,不會阻塞主執行緒。
LocalStorage
✗ 同步(會阻塞 UI)
✗ 最多 5MB
✗ 只能存字串
✗ 沒有索引查詢
✓ API 簡單
適合:少量設定、用戶偏好
IndexedDB
✓ 非同步(不阻塞 UI)
✓ 可達數百 MB 甚至 GB
✓ 支援物件、Blob、ArrayBuffer
✓ 支援索引查詢
✓ 支援事務(原子性操作)
適合:離線 App、大量資料快取
用 idb 庫(IndexedDB 的 Promise 包裝)
原生 IndexedDB API 是基於事件的,寫起來相當繁瑣。idb 庫提供 Promise 化的包裝以及完整的 TypeScript 型別支援,讓 IndexedDB 的使用體驗接近 async/await 的直覺感。
IndexedDB 實際應用場景
- • 離線優先 App:先從 IndexedDB 讀取資料顯示,背景更新後再同步。
- • 草稿自動儲存:每隔幾秒把編輯器內容存入 IndexedDB,防止意外關閉遺失。
- • API 回應快取:把 API 結果存起來,相同請求直接從本地讀取,節省網路請求。
- • 大型資源離線:把 PDF、圖片等 Blob 儲存在 IndexedDB 供離線存取。
Section 5:ResizeObserver — 偵測元素大小變化
傳統做法是監聽 window.resize 事件,但這只能偵測視窗大小,無法偵測特定元素的大小變化(例如側邊欄展開收合、動態內容導致父容器改變大小)。ResizeObserver 正是為這個場景而生。
ResizeObserver vs window.resize
- • ResizeObserver 監聽特定元素,window.resize 只監聽視窗
- • ResizeObserver 在元素大小變化的「微任務」中觸發,更即時
- • 不需要 throttle/debounce,瀏覽器已處理批次更新
- • 支援同時觀察多個元素
注意:避免 ResizeObserver Loop
如果在 ResizeObserver callback 中修改被觀察元素的大小(例如:setState 觸發重新渲染並改變 DOM),可能造成無限循環。最好只讀取大小,不直接修改被觀察元素。
Section 6:Page Visibility API — 用戶離開頁面了嗎?
Page Visibility API 讓你知道用戶目前是否在看這個頁面——他們切換到其他分頁、最小化視窗、或鎖定螢幕時,document.hidden 會變成 true。善用這個 API,可以暫停不必要的 CPU/網路消耗,節省用戶的電量和流量。
Page Visibility 使用場景整理
• 影片/音樂播放器(切換分頁自動暫停)
• 即時資料輪詢(頁面不可見時暫停)
• 遊戲(切換分頁暫停遊戲進度)
• 分析追蹤(計算用戶真實在場時間)
• WebSocket 連線管理(暫停心跳)
• 動畫(不在視窗中時暫停 requestAnimationFrame)
Section 7:Web Crypto API — 瀏覽器端加密
Web Crypto API(crypto.subtle)是瀏覽器內建的密碼學 API,支援 AES、RSA、ECDH 等常見加密演算法,以及 SHA-256、SHA-512 等雜湊函式。在瀏覽器端就能完成加密,不需要把敏感資料送到後端。
為什麼用 Web Crypto 而不是第三方加密庫?
Web Crypto API 由瀏覽器原生實作,使用硬體加速,效能遠優於純 JavaScript 的加密庫。它也不需要加到 bundle,零成本引入。此外,Web Crypto 是 FIPS 140-2 合規的實作,比大多數第三方庫更受信任。
crypto.randomUUID()
生成 v4 UUID,比 Math.random() 更安全
crypto.getRandomValues()
生成密碼學安全的隨機數(IV、Salt、Token)
crypto.subtle.digest()
SHA-256/512 雜湊,資料完整性驗證
這些 Web API 改變你的思維方式
學完這些 API,你會發現瀏覽器本身就是一個非常強大的執行環境。很多你以為「必須靠後端或第三方庫」才能做到的事,其實瀏覽器原生就支援:多執行緒計算(Web Workers)、大型資料庫(IndexedDB)、高效 DOM 監聽(Observer APIs)、加密(Web Crypto)。善用這些工具,你的應用會更快、更省流量、用戶體驗更好。