什么是 PWA
PWA(Progressive Web App)是一种新型的 Web 应用程序,它打破了传统网页与原生应用之间的界限,拥有近似原生应用的交互体验和功能。与传统的 Web 应用程序不同,PWA 具备以下特点:
- 安装性:可以通过添加到主屏幕、启动画面等方式安装到用户设备上,具备离线功能。
- 响应式:可以适配不同设备屏幕大小及分辨率。
- 快速加载:在网络情况不佳的情况下,也能快速加载内容。
- 优化的 UI:具备原生应用风格的 UI。
- 更新及时:可以实时接收推送通知、自动更新等功能。
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 开发时,常常遇到一些调试问题,如:
- 缓存数据无法更新
- Service Worker 更新失败
- 离线缓存失效
以下分享一些调试技巧,帮助你更好地排查问题。
缓存数据无法更新
当应用更新后,缓存数据无法更新,可能是由于浏览器对 Service Worker 的更新机制造成的。为了避免缓存中的数据过期,Service Worker 默认会对文件进行缓存,通常缓存时间是永久性的。
为了解决缓存数据无法更新的问题,可以在 Service Worker 的安装阶段中增加一个缓存清理功能。
-- -------------------- ---- ------- -------------------------------- ----- -- - -- ------- ---------------- ----------------------------- -- - ------ ------------ --------------------------- -- - ------ ------------------------------ -- --------- --- -------------- ---------------- -- - ------ ------------------------- -- -- -- -- -- --------- ---------------- ------------------------------------- -- - ------ ----------------------------- -- -- ---展开代码
在上面的代码中,在 Service Worker 安装阶段清空旧版本的缓存,然后再注册并缓存核心文件。
Service Worker 更新失败
当 Service Worker 更新失败时,可能是因为 Service Worker 中缓存的文件未更改所导致。为了解决这个问题,可以在主 HTML 文件中添加一个版本号,每次更新版本号以强制浏览器更新 Service Worker。
-- -------------------- ---- ------- ---- ---------- --- ------ ------ --- -------- ----- ---------- - ----------- ----- -------------- - - ---- -------------- ----------------- --- -- -- ----- ----- ------- - -- --- --------- ----- -------------- ---------------------- --- ------- ------ --- ------- -------展开代码
在上面的代码中,在脚本中定义了一个版本号变量 VERSION,每次更新版本号,即可强制浏览器更新 Service Worker 中的缓存文件。
离线缓存失效
当应用离线缓存失效时,可能需要查看当前缓存状态,以及 Service Worker 中缓存的文件是否正确。在 Chrome 开发者工具中,我们可以通过下面的步骤来查看:
- 打开开发者工具,选择 Application 面板。
- 在左侧导航栏中选择 Cache Storage。
- 选择对应的缓存存储区,即可查看当前缓存状态。
如果需要更新缓存,则可以使用以下两种方法:
- 修改缓存名称,手动更新缓存。
- 修改缓存文件,从而强制浏览器更新缓存。
结语
PWA 作为新型的 Web 应用开发方式,具备离线访问、优化的 UI、自动更新等功能,并且只需要用 HTML、CSS 和 JavaScript 三种语言就可以实现。在 PWA 开发中,数据管理和调试是很重要的两个方面,我们需要使用 Service Worker、IndexedDB、localStorage 等方式来管理数据,使用开发者工具、修改版本号等方法来调试和排查问题。希望这篇文章对大家有所帮助。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67b81cb7306f20b3a659e696