Web Workers检测前端版本更新

290 阅读1分钟

代码

import { Modal } from 'antd';

const createVersionWorker = () => {
  const blob = new Blob(
    [
      `
  self.onmessage = function (event) {
    let versionTag = null; // 版本标识
    let timer = undefined;
    
    
    /**
     * 获取首页的 ETag 或 Last-Modified 值,作为当前版本标识
     * @returns {Promise<string|null>} 返回 ETag 或 Last-Modified 值
     */
    const getVersionTag = async () => {
      const response = await fetch(event.data.docUrl, {
        cache: 'no-cache'
      });
      return response.headers.get('etag') || response.headers.get('last-modified');
    };
    
    /**
     * 比较当前的 ETag 或 Last-Modified 值与最新获取的值
     */
    const compareTag = async () => {
      const newVersionTag = await getVersionTag();
    
      if (versionTag === null) {
        // 初次运行时,存储当前的 ETag 或 Last-Modified 值
        versionTag = newVersionTag;
      } else if (versionTag !== newVersionTag) {
        // 如果 ETag 或 Last-Modified 发生变化,则认为有更新
        console.info('更新了', {
          oldVersionTag: versionTag,
          newVersionTag: newVersionTag
        });
        // 清除定时器
        clearInterval(timer);
        // 提示用户更新
        self.postMessage({});
      } else {
        // 没有更新
        console.info('没更新', {
          oldVersionTag: versionTag,
          newVersionTag: newVersionTag
        });
      }
    };
    
    // 每10秒检查一次是否有新的 ETag 或 Last-Modified 值
    timer = setInterval(compareTag, 1000);
    
  }
    `
    ],
    { type: 'application/javascript' }
  );
  const workerUrl = URL.createObjectURL(blob);
  const worker = new Worker(workerUrl);
  URL.revokeObjectURL(workerUrl);

  worker.postMessage({ docUrl: window.location.origin + window.location.pathname });
  return worker;
};

if (import.meta.env.MODE === 'production') {
  const worker = createVersionWorker();
  worker.onmessage = function () {
    worker.terminate();
    Modal.confirm({
      centered: true,
      title: '更新提示',
      content: '检测到新版本,建议立即更新以确保平台正常使用。',
      okText: '确认更新',
      cancelText: '稍后更新',
      onOk: () => {
        window.location.reload();
      }
    });
  };
}

参考

纯前端怎么实现检测版本更新,看这一篇就够了!

前端性能优化:使用 Web Workers 实现轮询