前言
PWA 是 Progressive Web App 的缩写,是基于网页技术构建的应用程序。PWA 具有快速、跨平台、离线访问等优点,越来越多的企业选择采用 PWA 技术来构建自己的应用。但是,PWA 在开发过程中存在自动更新的问题:如何让用户使用最新的应用程序版本?本文将介绍如何在 PWA 中实现自动更新。
PWA 的自动更新原理
在 PWA 中实现自动更新,需要了解其原理。当用户打开 PWA 应用程序时,浏览器会验证最新版本的应用程序是否可用。如果有新版本可用,浏览器会下载该版本并缓存在本地。这时,页面中的最新服务工作线程会接管页面,并更新应用程序。
如何在 PWA 中实现自动更新
1. 编写服务工作线程代码
在 PWA 中,服务工作线程扮演着重要角色。它是运行在后台的 JavaScript 程序,可以拦截网络请求、自动缓存请求,以及实现自动更新等功能。下面是一个简单的服务工作线程代码样例:
-- -------------------- ---- ------- ----- ---------- - ------------ ----- ----------- - - ---- -------------- -------------- --------- -- -------------------------------- ------- -- - ---------------- ----------------------- ------------- -- - ------ -------------------------- -- -- --- ------------------------------ ------- -- - ------------------ --------------------------- ---------------- -- - -- ---------- - ------ --------- - ------ --------------------- -- -- --- --------------------------------- ------- -- - ----- -------------- - ------------- ---------------- ---------------------------- -- - ------ ----------------------------- -- - -- ---------------------------- --- --- - ------ ------------------- - ---- -- -- ---
在上述代码中,通过监听 install 事件,将 PWA 应用的所有资源添加到缓存中。在 fetch 事件中,处理 HTTP 请求并从缓存中读取响应。在 activate 事件中,清除旧的缓存(cache)并更新新的缓存,确保更新的资源被正确地添加到缓存中。
2. 利用 serviceWorker.register()
方法注册服务工作线程
在 PWA 中注册服务工作线程是很容易的。只需要在应用程序中添加如下代码:
-- -------------------- ---- ------- -- ---------------- -- ---------- - ------------------------------- -- -- - ----------------------------------------------------- -------------------- -- - -------------------------- ------------ ---------- ---- ------ -- -------------------- -- ------------ -- - ---------------------------- ------------ ------- -- ----- --- --- -
上述代码通过 navigator.serviceWorker.register()
方法来注册服务工作线程。在注册成功之后,可以通过 registration.scope
属性获取服务工作线程的作用域。通过监听 load
事件,可以确保注册服务工作线程是在页面加载完成后执行的。
3. 判断是否有新版本可用
在服务工作线程中,可以通过以下代码完成新增自动更新功能:
-- -------------------- ---- ------- -------------------------------- ------- -- - -- ----------- --- -------------- - ------------------- - --- -- - ------- ------------- ------------------- -- ------------------ -- - -------- ------------- --------------------- -- ---------- -- - ----- ---- ----- ----- ---------- -------------------------------- ------- -- - ---------------- ----------------------- ------------- -- - ------ -------------------------- -- -- --- ------------------------------ ------- -- - ------------------ --------------------------- ---------------- -- - -- ---------- - ------ --------- - --- ------------ - ---------------------- ------ ------------------------- ---------- -- - -- ---------- -- --------------- --- --- -- ------------- --- -------- - ------ --------- - --- --------------- - ----------------- ----------------------- ------------- -- - ------------------------ ----------------- --- ------ --------- - -- -- -- --- --------------------------------- ------- -- - ----- -------------- - ------------- ---------------- ---------------------------- -- - ------ ----------------------------- -- - -- ---------------------------- --- --- - ------ ------------------- - ---- -- -- --------------------- -- ---------- --- -------------------------------- ------- -- - -- ----------- --- -------------- - ------------------- - --- -------------------------------- ------- -- - ---------------- ----------------------- ------------- -- - ------ -------------------------- -- -- --- --- --------------------- - ------ --- ------ - --- --- ---------- - ------ -------------------------------- -------- ------- - -- ----------- --- -------------- - --------------------- - ----- -- ------------ - ------ --- ---- -------- --- ------- ------- - ------ - ------------- ---------- - ----- ------ --------------------- ------ ---- ------- --- ------------- ----- ---- ----- ------------- - -- ----------- --- ------------------ - --------------------- - ------ -- ------------ - ------ --- ---- -------- --- ------- ------- - ------ - ------------- ---------- - ----- ------ --------------------- ------ ---- ------- --- ------------- ----- ---- ----- ------------- - --- -- --------- - -------------------- -- --------- ---------------------------------- ------- ------- ------- ----- --- --------------------------------- ----- -- - --------------------- ---------- -- --------------- ---- ---- ------ -- --- ------ ------ --- --- ------- ---- -- ----- --- ------- ----- --- -------- --- ------ ------- --- - --- ------ -- -- ---- -------- --------------------- --- ------ - --- ------- ------ ----- ----- ------ --- --------------------- ----- --------------------------------- --------------- - ---------------- --------------------------------------- - ------ ------------ ---------------------------------- - ------------------------------------------- - --------------------- ------- -------- ------ -------------- ------ ------------------------- ----- -- ----------- --- --------- -- ----------------------------- - ------ ------------------------- - -- -- -- -- --- ------------------------------------------------------------- ------------------------------ --- ------------------------------------------------- --- ------------------------------- ---------- --------- -------- - --- --------------------------- -------------- -- - -- - -- - -- -- -- -- -- - ---- - -------------------- ------ ------- -
首先,通过添加 self.addEventListener('message', (event) => { ... })
监听器来接收其他线程的消息。当其他线程发送 "skipWaiting" 消息时,服务工作线程将强制更新并跳过等待状态。并将 isNewVersionAvailable 设置为 true,在下一次重载时,可以将服务工作线程强制更新。在监听 activate 事件时,新版本的服务工作线程将取消等待状态,并接管其他客户端。这样,在新版本发布时,所有用户都可以运行最新的服务工作线程。
4. 发布新版本
现在,除了在服务工作线程中添加自动更新组件之外,还需要发布新版本。代码已准备好进行修改,只需要为新版本创建新的缓存。在新版本发布之后,将 "skipWaiting" 消息发送到服务工作线程,以启动新版本的服务工作线程,如下所示:
-- -------------------- ---- ------- -- ------- -- ---------------------- -- ---------- --- --------------- - -- ------------- --- ------------ - ------------------------- ------- - ---------------------------------- ------------------------- ------------------------- -
在新版本发布后,还需要向用户通知更新可用。为此,可以在页面中添加一个按钮或其他元素,提示用户可以刷新应用程序以获取最新版本,如下所示:
if (worker) { document.querySelector('.refresh').addEventListener('click', () => { worker.postMessage('skipWaiting'); }); }
结论
在 PWA 中,自动更新是很重要的。不过,实现自动更新不是很难,只需要编写服务工作线程代码,调用 navigator.serviceWorker.register()
方法来注册服务工作线程,判断是否有新版本可用,向用户通知更新可用,发布新版本等即可。希望这篇文章对你有所帮助!
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6700ee1c0bef792019ae283b