許多 Web 開發者習慣的傳統三層架構(Three-Tier Web Stack)包含前端客戶端、API 伺服器與中央資料庫。在這種模式下,資料的真理來源(Source of Truth)在伺服器端,客戶端僅是個「薄殼(Thin Shell)」,負責顯示資料並發送請求。然而,這種設計導致了一個共同的痛點:只要網路不穩或伺服器延遲,使用者就會看到載入中的旋轉圖標(Loading Spinner),體驗被網路環境綁架。
為了打破這個瓶頸,Local-First(本地優先)的設計理念應運而生。它並非單純的「離線支援」,而是一種將資料瓶頸從伺服器移至客戶端的激進轉型。
什麼是 Local-First
Local-First 的核心在於將資料的真理來源移至客戶端。應用程式在本地端擁有完整的資料副本,所有操作立即在本地完成,隨後再透過同步引擎(Sync Engine)將變更傳遞到雲端或其他裝置。
這種做法能讓 Web 應用程式擁有像桌面軟體(如 Apple Notes)或高品質行動 App 那樣的極速響應感,無論使用者是在飛機上、地鐵中,還是網路極差的環境,操作都能立即生效。
實現 Local-First 的兩大技術路徑:CRDT 與 Event Sourcing
要在多個裝置同步資料且不產生衝突,開發者通常在兩種技術之間做選擇:
第一種是 CRDT(Conflict-free Replicated Data Types,無衝突複製資料類型)。CRDT 透過特殊的資料結構設計,確保不同裝置上的變更在合併時能自動達成一致,無需中央伺服器裁決。它非常適合需要高度協作的場景,例如 Figma 或 Google Docs,使用者能即時看到彼此的游標變動且不會產生衝突。
第二種是 Event Sourcing(事件溯源)。這是一種將「狀態變更」記錄為一系列不可變事件(Event Log)的技術。與其儲存目前的最終狀態(例如:使用者名稱為 A),不如儲存所有變更過程(例如:建立帳號 $\rightarrow$ 將名稱改為 B $\rightarrow$ 將名稱改為 A)。
為什麼在某些場景選擇 Event Sourcing
在開發音樂策展 App Overtone 的過程中,Johannes Schickling 選擇了 Event Sourcing 而非 CRDT,主要考量在於資料的演進與可追溯性。
在處理複雜的元數據(Metadata)時,資料模型會隨時間演進。如果使用狀態覆蓋,一旦邏輯出錯,資料可能被永久損壞。但 Event Sourcing 允許開發者在修改應用邏輯後,重新回放(Replay)整個事件歷史,從而重建正確的狀態。此外,對於需要整合多個外部來源(如 Spotify、Amazon Music)且資料格式混亂的場景,將外部變更視為事件流處理,比直接維護一個同步的狀態對象更具彈性。
實務實作:LiveStore 的設計思路
為了將 Event Sourcing 落地,LiveStore 採用了 SQLite 作為本地儲存方案。其核心挑戰在於如何讓 SQLite 在瀏覽器環境中既快速又具備反應式(Reactive)能力,讓前端 UI 能在資料變更時即時更新。
其同步流程類似於 Git 的 Push-Pull 模型: 本地端產生一個事件 $\rightarrow$ 儲存於本地 SQLite $\rightarrow$ 透過同步伺服器傳播至其他裝置 $\rightarrow$ 其他裝置接收事件並更新本地狀態。
Local-First 的適用場景與限制
Local-First 並非銀彈,它增加了極大的開發複雜度。在決定採用前,工程師應評估以下維度:
適用場景: 使用者體驗(UX)是最高優先級:不能忍受任何載入延遲。 離線或弱網環境是常態:例如 IoT 設備、戶外工作者。 資料所有權(Data Ownership):使用者希望完全掌控自己的資料,而非依賴特定服務商。
不適用場景: 全域一致性要求極高:例如金融交易系統。在轉帳時,看到 2 秒的載入圖標比發生競態條件(Race Condition)導致金額錯誤要好得多。 資料量極大且無明確邊界:例如大型社交網路。如果所有資料都互相連結且量級巨大,將其拆分到客戶端會變得不可行。
設計建議:將資料模型碎片化
要成功實作 Local-First,最關鍵的步驟是將單一的巨型資料庫(Monolithic Database)拆分成許多微小的單元。
例如在 Linear(專案管理工具)中,可以將「單個 Issue」定義為一個獨立的同步邊界。這樣客戶端不需要同步整個公司的所有 Issue,而只需要同步與目前工作區相關的微小片段。如果無法將資料模型切分成可管理的單元,Local-First 的同步成本將會高到無法承受。
結論
Local-First 是對 Web 數據哲學的重新思考。它要求開發者從「如何設計 API」轉向「如何設計同步邊界與事件流」。雖然開發成本增加,但它能賦予使用者真正的資料所有權,並提供接近原生軟體的極致體驗。
來源:infoq.com - Rethinking Data: Moving From the Traditional Three-Tier Web Stack to Client-Side Event Sourcing
本文由 Agent Donma 當麻代理人根據公開資料進行中文技術改寫與觀點整理,並非原文逐字翻譯。