前端重新部署如何使用WebWorker优雅地通知用户刷新网页?

背景

当周五晚上我正准备享用美味的宵夜时,突然接到了一个紧急消息,组里的前端系统出现了bug。我皱起了眉头,放下手中的美食,立即打开了钉钉,查看了具体情况。

原来,这个bug实际上是前几天才解决过的问题。我用手指在屏幕上滑动,果然发现了解决之道------只需简单地刷新页面。原因竟是用户一直停留在页面上,而新版本发布后,他们没有及时刷新页面,导致无法获取到最新的资源。

这让我想起了一个有趣的小故事:有一次,一个小村庄里的农夫决定要建造一个全新的小桥,以便于村民们更便利地过河。他精心设计了桥梁,使用了最先进的材料。然而,当桥梁完工后,他发现村民们仍然习惯于原来的狭窄破旧的木桥,而不愿意使用新桥。原来,他们根本不知道有新桥的存在,因为从来没有人告诉过他们。

解决方案

  1. 添加manifest.json文件记录版本信息:这是一个很好的做法,可以方便地记录前端应用的版本信息。

  2. 打包时写入当前时间戳信息 :这种方式可以确保每次打包都会更新manifest.json中的版本信息,以便后续的版本比较。

  3. 引入检查更新逻辑:在入口JS中引入检查更新的逻辑是非常好的,这样可以确保应用启动时就会进行版本检查。

  • 路由守卫检查更新:使用路由守卫进行检查更新是一个不错的选择,因为它可以确保在用户每次导航到页面时都会进行检查。

  • 使用Worker轮询检查更新:这种方法也可以,但需要注意轮询的频率,过于频繁的轮询可能会给服务器带来不必要的负担。而且使用Worker可能会增加一些复杂性。

案列

  1. public文件夹下创建一个manifest.json文件,用于记录版本信息。在public文件夹下新建manifest.json文件,并写入以下内容:
javascript 复制代码
{
  "timestamp": 0,
  "msg": "这是一个示例更新提示信息"
}
  1. 修改public/index.html文件,将标签中的修改为你项目的名称,并在标签中添加以下代码,用于引入manifest.json文件:
javascript 复制代码
<link rel="manifest" href="<%= BASE_URL %>manifest.json" />
  1. 在Vue项目中的入口文件src/main.js中,引入检查更新的逻辑:
javascript 复制代码
import Vue from 'vue'
import App from './App.vue'
import router from './router'

Vue.config.productionTip = false

// 引入检查更新逻辑
import '@/utils/checkUpdate'

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')
  1. 创建一个工具类文件src/utils/checkUpdate.js,用于实现检查更新的逻辑:
javascript 复制代码
import router from '@/router'
import { Modal } from 'ant-design-vue'

if (process.env.NODE_ENV === 'production') {
  let lastEtag = ''
  let hasUpdate = false
  let worker = null

  async function checkUpdate() {
    try {
      let response = await fetch(`/manifest.json?v=${Date.now()}`, {
        method: 'head'
      })
      let etag = response.headers.get('etag')
      hasUpdate = lastEtag && etag !== lastEtag
      lastEtag = etag
    } catch (e) {
      return Promise.reject(e)
    }
  }

  async function confirmReload(msg = '', lastEtag) {
    worker &&
      worker.postMessage({
        type: 'pause'
      })
    try {
      Modal.confirm({
        title: '温馨提示',
        content: '系统后台有更新,请点击"立即刷新"刷新页面\n' + msg,
        okText: '立即刷新',
        cancelText: '5分钟后提示我',
        onOk() {
          worker.postMessage({
            type: 'destroy'
          })
          location.reload()
        },
        onCancel() {
          worker &&
            worker.postMessage({
              type: 'recheck',
              lastEtag: lastEtag
            })
        }
      })
    } catch (e) {}
  }

  router.beforeResolve(async (to, from, next) => {
    next()
    try {
      await checkUpdate()
      if (hasUpdate) {
        worker.postMessage({
          type: 'destroy'
        })
        location.reload()
      }
    } catch (e) {}
  })

  worker = new Worker(
    new URL('../worker/checkUpdate.worker.js', import.meta.url)
  )

  worker.postMessage({
    type: 'check'
  })
  worker.onmessage = ({ data }) => {
    if (data.type === 'hasUpdate') {
      hasUpdate = true
      confirmReload(data.msg, data.lastEtag)
    }
  }
}
  1. 创建一个Worker文件src/worker/checkUpdate.worker.js,用于实现Worker的逻辑:
javascript 复制代码
let lastEtag
let hasUpdate = false
let intervalId = ''
async function checkUpdate() {
  try {
    let response = await fetch(`/manifest.json?v=${Date.now()}`, {
      method: 'get'
    })
    let etag = response.headers.get('etag')
    let data = await response.json()
    hasUpdate = lastEtag !== undefined && etag !== lastEtag
    if (hasUpdate) {
      postMessage({
        type: 'hasUpdate',
        msg: data.msg,
        lastEtag: lastEtag,
        etag: etag
      })
    }
    lastEtag = etag
  } catch (e) {
    return Promise.reject(e)
  }
}

addEventListener('message', ({ data }) => {
  if (data.type === 'check') {
    checkUpdate()
    intervalId = setInterval(checkUpdate, 5 * 60 * 1000)
  }
  if (data.type === 'recheck') {
    hasUpdate = false
    lastEtag = data.lastEtag
    intervalId = setInterval(checkUpdate, 5 * 60 * 1000)
  }
  if (data.type === 'pause') {
    clearInterval(intervalId)
  }
  if (data.type === 'destroy') {
    clearInterval(intervalId)
    close()
  }
})

以上就是一个简单的案例,你可以在Vue项目中测试一下自动检查更新并提示用户刷新页面的功能。记得在实际项目中根据具体情况做适当的调整和优化。

相关推荐
掘了6 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅6 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅6 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅7 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment7 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅7 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊7 小时前
jwt介绍
前端
爱敲代码的小鱼7 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
Cobyte7 小时前
AI全栈实战:使用 Python+LangChain+Vue3 构建一个 LLM 聊天应用
前端·后端·aigc
NEXT068 小时前
前端算法:从 O(n²) 到 O(n),列表转树的极致优化
前端·数据结构·算法