iT邦幫忙

2026 iThome 鐵人賽

DAY 22
0
Modern Web

從 UI/UX 設計到前端實作:30 天打造專屬的任務學習計時器系列 第 22 篇

DAY 22|Local-First 架構(一):什麼是 Local-First?為什麼選擇使用 IndexedDB?

  • 分享至 

  • xImage
  •  

一開始在規劃 TaskTimer 時,我的核心目標非常明確——簡潔方便、功能單純。

我希望它是一個能讓使用者隨開即用、沒有任何學習門檻的小幫手。更重要的是,我希望它 就算在離線狀態下使用也不受任何影響;同時,盡可能不收集使用者的個人資料,保護隱私與數據安全。

在查詢一些資料後,我發現 Local-First(本地優先) 這個架構理念,很符合我的需求。


一、什麼是 Local-First 架構?

Local-First(本地優先) 的核心思想是:「資料的主權屬於使用者,且應用程式的核心功能必須能在本地端獨立運作。」

Local-First 的三大優勢:

1. 極致的順暢度(Zero Latency):所有資料讀寫都在瀏覽器內部完成,不需要等待網路 Request 反應,使用者可以順暢操作。

2. 離線即服務(Offline-Ready):就算完全斷開網路,使用者依然可以新增任務、開始計時、寫下備註與查看歷史紀錄。

3. 資料隱私與掌控權:使用者的數據與備註不會預設上傳到第三方伺服器,資料儲存在使用者自己的裝置上,完全保障隱私。


二、Web 儲存方案比一比:LocalStorage vs. IndexedDB

前端常見的本地儲存機制主要有 LocalStorage 與 IndexedDB,兩者的特性差異如下:

特性 LocalStorage IndexedDB
資料 僅支援字串 (Key-Value) 支援結構化物件 (JSON Object/Array)
容量限制 極小(通常約 5MB) 極大(通常可達 幾百 MB 以上)
執行方式 同步 (Synchronous),會阻塞 UI 主執行緒 非同步 (Asynchronous),不卡死 UI 渲染
查詢能力 只能靠 Key 取值,複雜查詢需全拉出解析 支援 Index (索引) 與範圍查詢

為什麼選擇使用 IndexedDB?

  1. 避免 Blocking UI:LocalStorage 是同步 API,當資料量變大(例如累積了幾百筆計時紀錄)時,讀寫操作會直接卡住瀏覽器的畫面渲染,造成使用時會有卡頓感。

  2. 原生支援 JSON 物件:目前的資料結構包含了主任務、子任務以及陣列形式的 records(計時紀錄)。LocalStorage 每次都必須手動 JSON.stringify 與 JSON.parse,而 IndexedDB 支援 NoSQL 形式的 Object Store,可以直接存取物件。

  3. 未來的擴充性:隨著紀錄越來越多,甚至未來加入圖表統計分析時,IndexedDB 的索引(Index)高效率地進行範圍查詢。


TaskTimer 的本地資料結構規劃

在之前的開發,記憶體(Memory)中使用了一個 tasks 陣列來維護全域狀態:

// MissionTimer 的核心資料結構
let tasks = [
  {
    id: "task-1",
    title: "iThome 2026鐵人賽",
    subtasks: [
      {
        id: "sub-1",
        title: "主題發想、描述",
        status: "completed",
        records: [
          {
            id: "rec-1",
            timeRange: "2026/9/14 22:25~22:45",
            durationMinutes: 20,
            note: "試用市面主流產品和自身需求的比較",
          }
        ],
      }
    ]
  }
];

在接下來的兩天中,將會建立一個 TaskTimerDB 的本地資料庫,並建立名為 tasks 的 Object Store(相當於關聯式資料庫的 Table),將這套結構完好地持久化到使用者的瀏覽器中。


(參考資料:Explain This - 本地優先 (local-first) 的軟體設計)
(參考資料:Mdn - IndexedDB API)


上一篇
DAY 21|數據統計:任務列表進度條與時間呈現
系列文
從 UI/UX 設計到前端實作:30 天打造專屬的任務學習計時器 共 22 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言