iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 29
0
Modern Web

30 天 Progressive Web App 學習筆記系列 第 29

Day 29 - 30 天 Progressive Web App 學習筆記 - 介紹 Offline Storage

為什麼要介紹 Offline Storage?

能夠在無網路存取的環境下進行『離線瀏覽』是 PWA 的強大特點,在 To-Do List 的範例中,我們已經透過 Service Worker 搭配 cache API 成功取得靜態資源和 GET 的資料,讓我們能夠順利離線瀏覽網站。

如果你的網站是單純以『內容』為主,只要透過 GET 就可以取得資源,那麼 Service Worker + cache API 就能夠滿足你的需求,但是以 To-Do List 為例,還有『POST-新增待辦清單』、『PUT-修改待辦清單』、『DELETE-刪除待辦清單』,則就必須考慮更多 Offline 策略,本篇希望能夠介紹有哪些 Offline Storage 可供選擇,以利因應較複雜的需求並執行更廣泛的應用。


有哪些 Offline Storage?

Web Storage 有很多種,列舉:

  • Cache
    • Data Model: key/value
    • Browser Support:60%
    • Sync/Async:Async
  • IndexedDB
    • Data Model: hybrid
    • Browser Support:83%
    • Sync/Async:Async
  • Local storage
    • Data Model: key/value
    • Browser Support:93%
    • Sync/Async:Sync
  • Web SQL(已被棄用)

有哪些 Offline Storage?

列舉部分 Offline Storage 個別介紹如下:

Cache

通常我們能夠藉由 Service Worker 和 Cache API 做完美的搭配,在之前文章的範例中,Service Worker 會去監聽 fetch 事件,攔截 request 並回傳 response。

Cache API 有很多種設定,不過以下圖為例,Service Worker 會去比對是否有已存在的 Cache:

  • 如果有,就直接回傳對應的 response
  • 如果沒有就透過 Network 發送 request 回傳 response 做 cache

最後再將 response 的資料內容,顯示至 Page。

透過 Cache API 在 fetch 事件裡進行操作,對應的程式碼如下:

self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.open('mysite-dynamic').then(function(cache) {
      return cache.match(event.request).then(function(response) {
        var fetchPromise = fetch(event.request).then(function(networkResponse) {
          cache.put(event.request, networkResponse.clone());
          return networkResponse;
        })
        return response || fetchPromise;
      })
    })
  );
});

Service Workers (and the Cache API) 目前支援 Chrome, Firefox, Opera,不過 Edge 仍在開發中。

圖片來源:Is ServiceWorker ready?


IndexedDB

介紹 IndexedDB 之前,先來看看 IndexedDB 的支援程度,約 83%

圖片來源:Can I use

IndexedDB 是什麼?

Indexed Database(IndexedDB)API 是 HTML5 的一部份,W3C 宣布 Web SQL database 停用之後,IndexedDB 取而代之,IndexedDB 能夠在 client 端儲存大量的結構化資料並提供高效率索引的 API。

額外分享如何透過 Chrome DevTools,查看 IndexedDB 資訊,進入 Application 點選 IndexedDB,可以查看 security origin, name, and version:

接著可以展開 IndexedDB 選單,點選 DB 名稱,查看 key-value pairs (KVPs)

實作部分可以參考這篇文章:"Instant Loading" with IndexedDB


Local storage

Web Storage 是 HTML5 的 Storage API,Web Storage 分為兩種,分別是 sessionStorage 和 localStorage,sessionStorage 的生命週期較短,只要瀏覽器視窗或分頁(tab)關閉就會消失,而 localStorage 的生命週期較長。

可以參考這篇文章:HTML5 Web Storage

此外一樣可以透過 Chrome DevTools,查看 Local storage 資訊如下:

圖片來源 - Inspect and Manage Storage, Databases, and Caches


Web SQL

雖然 Google 的 Chrome DevTools 文件裡,還有提到 Web SQL,但 W3C 已經在 2010/11/18 宣布 Web SQL database 被棄用(Deprecated),所以不建議使用此技術。

詳細資訊可以參考 html5rocks 的這篇文章,裡面提到 WebSQL 和 IndexedDB 的差異,以及為什麼應該使用 IndexedDB 的原因:Migrating your WebSQL DB to IndexedDB


建議使用哪種 Offline Storage?

Offline Storage for Progressive Web Apps 裡面有提到:

Let’s get right to the point with a general recommendation for storing data offline:

For URL addressable resources, use the Cache API (part of service workers).

For all other data, use IndexedDB (with a Promises wrapper).

理由是 Cache APIIndexedDB 都是非同步 (IndexedDB is event based and the Cache API is Promise based),均可以在 web workers、window、service workers 這三種環境裡運作。

為什麼不用其他的 storage 機制?

Web Storage(例如 LocalStorage and SessionStorage)是同步的,在 Web Worker 的環境裡無法運行,加上檔案大小和類型也受到限制。

Cookie 是同步的,也同樣會有檔案大小的限制以及 web worker 無法運行的問題。

WebSQL 在前面的介紹有提到、WebSQL 沒有廣泛的瀏覽器支持也已經被廢棄,所以不建議使用。


今日小結

你可以 cache 靜態資源,藉由 Cache API 去儲存你的 application shell (JS/CSS/HTML files),再透過 IndexedDB 取得動態資料。

這邊再介紹 Pokedex Progressive Web App 的案例,Pokedex 主要是使用 Cache APIIndexedDB 作為 Offline Storage。

能夠透過 URL 取得的資源,將使用 Cache API 來做快取,而藉由 IndexedDB 用來儲存應用程式的狀態。


參考文件


本人小小筆記,如有錯誤或需要改進的部分,歡迎給予回饋。
我將會用最快的速度修正,m(_ _)m。謝謝

上一篇
Day 28 - 30 天 Progressive Web App 學習筆記 - To-Do List 搭配 React + Redux 實作 PWA
下一篇
Day 30 - 30 天 Progressive Web App 學習筆記 - 最終回《也是一個新的開始》
系列文
30 天 Progressive Web App 學習筆記30

尚未有邦友留言

立即登入留言