美文网首页
纯前端实现发版版本变化后页面重新加载

纯前端实现发版版本变化后页面重新加载

作者: storyWrite | 来源:发表于2023-02-10 11:34 被阅读0次

    0.原理

    • 通过在前端静态文件目录下维护一个版本,首次进入页面存储当前版本,轮询查询静态文件版本是否发生变化,
      如果变化则重新加载页面,如果未变化,则继续轮询
    image.png

    1. 优点

    • 比通过后端维护在数据库版本进行查询消耗更小,不需要查询数据库,也不用走到后台代码层,只需要访问到ngxin/appache层
    • 并且维护纯依靠前端,可控(也可以通过检测/index.html中的js文件hash值,但是不可控,如果发版内容不需要页面进行刷新,则无法做到)

    2.优化

    • 为减少请求数量,当浏览器最小化,或不在当前标签内则停止查询
    • 当用户10min(可自定义修改时间)内不操作页面(不点击页面),也停止检测,直到操作页面后,继续进行检测,10min内不操作,则停止检测
    • 如果项目使用人数极多,达到5w以上还可以将轮询改为,当用户点击页面后再进行版本检测

    3.代码

    1).检测代码

    // 检测版本是否有变化 有变化则刷新页面
    import version from '../public/assets/version.json';
    
    export default const versionCheck = () => {
      const checkTime = 5000; // 检测版本请求时间间隔
      const clickTime = 5000; // 检测操作时间间隔 每5s检测是否用户超时未操作
      const stopDifferTime = 600000; // 停止检测的时间条件 10min 1000 * 60 * 10 10min不操作,则不再检测
      window._version = version.version;
      window.stopVersionCheck = () => {};
      window.stopClickCheck = () => {};
      async function getVersion() {
        let res = await fetch(`/assets/config/version.json?random=${Math.random()}`);
        let { version } = await res.json();
        console.log(version, window._version);
    
        if (version !== window._version) {
          window._version = version;
          return true;
        }
        return false;
      }
      async function checkNeedReloadPage() {
        window.stopVersionCheck();
        let timer = setInterval(async () => {
          // 影响查看控制台接口(如果localStorage存在key为timer的值) 直接清楚掉定时器 不检测
          if (localStorage.getItem('timer') !== null) {
            window.stopVersionCheck();
            window.stopClickCheck();
          }
    
          let changeVersion = await getVersion();
          if (changeVersion) {
            console.log('版本发生变化 开始重新加载');
            window.location.reload();
          }
        }, checkTime);
        window._timer = true;
        // 停止版本检测请求 便于调试
        window.stopVersionCheck = () => {
          window._timer = false;
          clearInterval(timer);
        };
      }
      function getSetCurrentTime() {
        localStorage.setItem('_time', new Date().getTime().toString());
        // 操作页面后 如果之前停止了检测 重新启动
        !window._timer && checkNeedReloadPage();
      }
    
      function visibilityChange() {
        if (document.visibilityState === 'hidden') {
          window.stopVersionCheck();
          window.stopClickCheck();
        } else {
          checkVersion();
        }
      }
      //   检查是否操作页面
      function checkVersion() {
        // 初始化时间
        getSetCurrentTime();
    
        if (localStorage.getItem('_time')) {
          // 每分钟检测一次 距离上次操作滚动页面时间 超过10分钟未滚动 则停止检测请求
          let timer = setInterval(() => {
            let _differTime = new Date().getTime() - Number(localStorage.getItem('_time'));
            console.log('_differTime', _differTime);
    
            if (_differTime > stopDifferTime) {
              window.stopVersionCheck();
            }
          }, clickTime);
          window.stopClickCheck = () => {
            clearInterval(timer);
          };
        }
      }
    
      function addEventListner() {
        // 检测用户是否点击界面  绑定在document 标签切换也会触发click事件
        document.addEventListener('click', getSetCurrentTime);
        // 如果窗口最小化或者不在当前页签 则不检测 减少请求次数
        document.addEventListener('visibilitychange', visibilityChange);
      }
    
      // 初始化
      addEventListner();
      checkVersion();
    };
    

    2).changeVersion.js 发版修改版本脚本

    // 用于发版后刷新页面  
    const fs = require('fs');
    const path = require('path');
    // 由于pub目录不在rootDir ts报错 pub下供轮训查询使用
    const filePathPub = path.resolve(__dirname, '../public/assets/config/version.json');
    // 读取 设置新版本
    const oldVersion = JSON.parse(fs.readFileSync(filePathPub).toString());
    console.log(oldVersion, 'change version before');
    const newVersion = JSON.stringify({ version: Math.random() });
    console.log(newVersion);
    fs.writeFileSync(filePathPub, newVersion);
    console.log(fs.readFileSync(filePathPub).toString(), 'pub 修改后');
    

    3).packge.json script脚本

        "publish:version":"node scripts/changeVersion.js && git add . && git commit -m \" 版本发布\" && git push ",
    

    4).version.json

    {
      "version": 1
    }
    

    4. 使用方式

    • 将versionCheck 在项目初始化时执行
    • 如果需要发布新版本,使页面刷新,则执行脚本yarn(npm run) publish:version

    相关文章

      网友评论

          本文标题:纯前端实现发版版本变化后页面重新加载

          本文链接:https://www.haomeiwen.com/subject/wprkkdtx.html