Skip to content

⚠️ Important Notice

This post was last updated on: which was . Please pay attention to its timelines.

背景

在前端项目部署更新到服务器之后,需要对用户的页面进行更新提示。

原理

  • 使用sharedWorker在worker线程中轮询
  • 轮询去查看资源是否更新etag、last-modified
  • 如果资源更新,再去判断版本号是否更新。通过接口拿到新的版本号,以及本地缓存代码中的版本号。
  • 如果版本号也更新,就弹出更新弹窗。

具体步骤

  1. 首先在sharedWorker中通过轮询去判断服务端资源是否有更新

    • 轮询就是setInterval
    • 判断服务端资源是否更新:通过HEAD访问/接口,后端接口处理时直接返回index.html文件即可。前端拿到响应头的etag或last-modified
      • 拿到最新资源标识后,前端通过对比判断资源是否更新
      • 如果更新进入下一步版本号的判断
      • HEAD请求:只返回头部信息,可以减少不必要的网络传输
  2. 判断版本号

    • 前端构建时,需要生成一个版本号,然后将版本号信息写入了 .env文件 以及 release.json文件
      • .env文件是为了后面代码中好获取版本号:直接注入环境变量内,通过process.env或者import.meta.env可以方便的获取。
      • release.json文件:一方面是为了后端服务好读取版本号信息,另一方面该文件也能加上版本更新的一些信息,比如哪些模块有更新等。
    • 后端接口:提供了一个/release接口,读取release.json文件,返回当前的版本信息。
    • 前端:前端调用接口,由于未刷新用的还是浏览器缓存下来的代码,此时通过对比本地的版本号以及拿到的最新版本信息对比即可
      • 如果版本号有更新,弹出更新弹窗

具体代码

这里写了一个极简的demo,可以按照readme.md操作一下。

思考

轮询机制是否有优化空间:需要看业务吧,如果使用websocket,后端服务就需要去监听文件是否变化,本质还是轮询,只是将压力放到了服务端。 如果业务很大,比如上百万的,可能还是轮询好一点,毕竟可以减少服务端压力;当然这样产品的性能就会略差一些。

上一次更新: