PWA 中的数据管理及调试技巧分享

阅读时长 12 分钟读完

什么是 PWA

PWA(Progressive Web App)是一种新型的 Web 应用程序,它打破了传统网页与原生应用之间的界限,拥有近似原生应用的交互体验和功能。与传统的 Web 应用程序不同,PWA 具备以下特点:

  1. 安装性:可以通过添加到主屏幕、启动画面等方式安装到用户设备上,具备离线功能。
  2. 响应式:可以适配不同设备屏幕大小及分辨率。
  3. 快速加载:在网络情况不佳的情况下,也能快速加载内容。
  4. 优化的 UI:具备原生应用风格的 UI。
  5. 更新及时:可以实时接收推送通知、自动更新等功能。

PWA 中的数据管理

在 PWA 开发中,数据管理并不是一件容易的事情。因为 PWA 要求具备离线功能,所以需要有一个类似本地缓存的机制,用于在离线时读取数据。Service Worker 是一个很好的选择。

Service Worker

Service Worker 是一个独立于当前 Web 页面的后台进程,它可以操作 Web 页面所在浏览器的缓存机制。通过 Service Worker,我们可以将一部分数据缓存在本地,从而支持离线访问。

在 PWA 中,通常我们需要使用 Service Worker 来缓存 App 的一些核心文件,以及用户的数据。

注册 Service Worker

要注册 Service Worker,首先需要在 main.js 中判断浏览器是否支持 Service Worker。

-- -------------------- ---- -------
-- ---------------- -- ---------- -
  ------------------------------- -- -- -
    ------------------------------------------------------------
      ------------ -- -
        -------------------------- ------------ ---------- ---- ------ -- --------------------
      --
      --- -- -
        -------------------------- ------------ ------- -- -----
      -
    --
  ---
-
展开代码

在上面的代码中,我们首先判断浏览器是否支持 Service Worker,然后将 Service Worker 脚本文件 /service-worker.js 注册到浏览器中。

Service Worker 缓存

Service Worker 中的缓存分为两种:预缓存和动态缓存。预缓存是指在应用安装或更新的时候缓存的一些核心文件,动态缓存是指在运行时缓存的其他文件。

对于预缓存,我们可以通过在 Service Worker 中编写类似以下代码来完成:

-- -------------------- ---- -------
-- ----------
----- ------------ - -
  ----
  --------------
  -----------------
  --------------
  ------------------
--

-------------------------------- ----- -- -
  -- -- ------- ------ -------
  ----------------
    ---------------------------------- -- -
      ------ ---------------------------
    --
  --
---

--------------------------------- ----- -- -
  -- -------
  ----------------
    ----------------------------- -- -
      ------ ------------
        --------------------------- -- -
          ------ ------------------------------ --
            --------- --- -----------
        ---------------- -- -
          ------ -------------------------
        --
      --
    --
  --
---
展开代码

在上面的代码中,我们首先定义了要缓存的文件列表 filesToCache,然后在 install 事件中将这些文件缓存到名为 myapp-v1 的缓存中。在 activate 事件中,我们可以将旧版本的缓存删除,以免占用过多空间。

对于动态缓存,我们可以使用 Fetch API 来实现。Fetch API 是一种以更灵活、更强大的方式进行网络请求的 API。

-- -------------------- ---- -------
------------------------------ ----- -- -
  ------------------
    ----------------------------------------- -- -
      -- ---------- -
        -- ----------------------
        ------ ---------
      -
      -- --------
      -- ------- -------- ------- --
      ------ ---------------------------------- -- -
        -- ------------
        ------ ---------------------------------- -- -
          -- --------- ---------------- --------
          -- ------------------------------------
          ------------------------ ------------------
          ------ ---------
        ---
      ---
    --
  --
---
展开代码

在上面的代码中,我们在 fetch 事件中首先尝试从缓存中获取该请求的结果。如果缓存中有,则直接返回缓存中的结果;否则发送网络请求获取结果,并将结果缓存到 myapp-v1 缓存中。

IndexedDB

Service Worker 只能缓存一些不太多的数据,对于大量的数据,PWA 中还有一个数据管理机制:IndexedDB。IndexedDB 是一个基于 JavaScript 的非关系型数据库,可以将大量的数据存储到本地。

IndexedDB 的使用方法如下:

-- -------------------- ---- -------
-- -----
--- ------- - --------------------------------- ---

-- -----------
----------------- - --------------- -
  -- - --------------------
  --------------------- ------ ---------------
-

-- -----------
--------------- - --------------- -
  ------------------------------------
-

-- -----------
----------------------- - --------------- -
  -- - --------------------
  -- ------ ----- -----
  --- ----------- - ----------------------------- - -------- ---- ---
  -- ------ ------------ ---
  --------------------------------------- ---------- - ------- ----- ---
-
展开代码

在上面的代码中,我们首先通过 window.indexedDB.open() 方法打开一个名为 myapp-db 的 IndexedDB 数据库。如果数据库打开成功,则会执行 request.onsuccess 事件处理程序;如果打开失败则会执行 request.onerror 事件处理程序。

如果需要升级数据库,则需要编写 request.onupgradeneeded 事件处理程序。在事件处理程序中,我们可以创建一个名为 notes 的对象仓库,并为该仓库创建一个名为 createdIndex 的索引。

在 IndexedDB 中读写数据的方法如下:

-- -------------------- ---- -------
-- ------------ ----- ----
--- -- - ----------------------- -------------
-- -- ----- ----
--- ----- - ------------------------

-- ------
--- ---- - -
  --- -----------
  ------ ----- -------
  -------- ----- ---------
  -------- --- -------
  --------- --- ------
--
----------------

-- ------
----------------

-- ------
---------------------- - --------------- -
  ---------------------------------
-

-- ------
------------------------ - --------------- -
  ---------------------------------
-
展开代码

在上面的代码中,我们新建一个事务,并指定要访问的对象仓库为 notes。然后使用 store.add() 方法向仓库中添加一条数据记录。使用 store.delete() 方法删除 ID 为 1 的数据记录。使用 store.get() 方法通过 ID 查询一条记录。使用 store.getAll() 查询所有记录。

localStorage

除了 IndexedDB,还有一个比较常用的数据管理方式,那就是 localStorage。

LocalStorage 是 Web Storage API 的一种,可以将数据以键-值对的形式存储在浏览器中。使用方法非常简单:

-- -------------------- ---- -------
-- ----
---------------------------- ---------

-- ----
--- ---- - -----------------------------
------------------

-- ----
--------------------------------

-- ------
---------------------
展开代码

LocalStorage 在使用时需要注意,因为它是以纯文本形式存储的,所以不适合存储大量结构化数据。

PWA 中的调试技巧

在 PWA 开发时,常常遇到一些调试问题,如:

  1. 缓存数据无法更新
  2. Service Worker 更新失败
  3. 离线缓存失效

以下分享一些调试技巧,帮助你更好地排查问题。

缓存数据无法更新

当应用更新后,缓存数据无法更新,可能是由于浏览器对 Service Worker 的更新机制造成的。为了避免缓存中的数据过期,Service Worker 默认会对文件进行缓存,通常缓存时间是永久性的。

为了解决缓存数据无法更新的问题,可以在 Service Worker 的安装阶段中增加一个缓存清理功能。

-- -------------------- ---- -------
-------------------------------- ----- -- -
  -- -------
  ----------------
    ----------------------------- -- -
      ------ ------------
        --------------------------- -- -
          ------ ------------------------------ --
            --------- --- --------------
        ---------------- -- -
          ------ -------------------------
        --
      --
    --
  --
  
  -- ---------
  ----------------
    ------------------------------------- -- -
      ------ -----------------------------
    --
  --
---
展开代码

在上面的代码中,在 Service Worker 安装阶段清空旧版本的缓存,然后再注册并缓存核心文件。

Service Worker 更新失败

当 Service Worker 更新失败时,可能是因为 Service Worker 中缓存的文件未更改所导致。为了解决这个问题,可以在主 HTML 文件中添加一个版本号,每次更新版本号以强制浏览器更新 Service Worker。

-- -------------------- ---- -------
---- ---------- ---
------
  ------
    ---
    --------
      ----- ---------- - -----------
      ----- -------------- - -
        ----
        --------------
        -----------------
        ---
      --
      -- -----
      ----- ------- - --
      ---
    ---------
    ----- -------------- ----------------------
    ---
  -------
  ------
    ---
  -------
-------
展开代码

在上面的代码中,在脚本中定义了一个版本号变量 VERSION,每次更新版本号,即可强制浏览器更新 Service Worker 中的缓存文件。

离线缓存失效

当应用离线缓存失效时,可能需要查看当前缓存状态,以及 Service Worker 中缓存的文件是否正确。在 Chrome 开发者工具中,我们可以通过下面的步骤来查看:

  1. 打开开发者工具,选择 Application 面板。
  2. 在左侧导航栏中选择 Cache Storage。
  3. 选择对应的缓存存储区,即可查看当前缓存状态。

如果需要更新缓存,则可以使用以下两种方法:

  1. 修改缓存名称,手动更新缓存。
  2. 修改缓存文件,从而强制浏览器更新缓存。

结语

PWA 作为新型的 Web 应用开发方式,具备离线访问、优化的 UI、自动更新等功能,并且只需要用 HTML、CSS 和 JavaScript 三种语言就可以实现。在 PWA 开发中,数据管理和调试是很重要的两个方面,我们需要使用 Service Worker、IndexedDB、localStorage 等方式来管理数据,使用开发者工具、修改版本号等方法来调试和排查问题。希望这篇文章对大家有所帮助。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67b81cb7306f20b3a659e696

纠错
反馈

纠错反馈