首页 > 其他分享 >纯前端实现发版版本变化后页面重新加载

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

时间:2024-04-15 10:45:12浏览次数:26  
标签:const 检测 window version 版本 发版 加载 页面

0.原理

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

image.png

1. 优点

  • 比通过后端维护在数据库版本进行查询消耗更小,不需要查询数据库,也不用走到后台代码层,只需要访问到ngxin/appache层
  • 并且维护纯依靠前端,可控(也可以通过检测/index.html中的js文件hash值,但是不可控,如果发版内容不需要页面进行刷新,则无法做到)
  • 可以结合jekins打包配置,自动进行版本通知
  • 可以做到即使用户在同一页面停留很长时间,也能将最新版本代码更新到用户端

缺点:

  • 占用请求数量,如果页面请求较多,可能会拖慢进度,可以添加策略处理,请求数量少时再进行处理
  • 资源没有合理利用(因为如果不发版则会导致大多数的请求是浪费的)

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分钟未滚动 则停止检测请求
      // 注意 小于1s的轮训在页面不可见的情况下(浏览器最小化、切换标签,浏览器会将执行时间固定为1s)
      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

==================================
更合理的方案应该是在路由变化的时候先进行版本检测,可以降低最终消耗,以及让接口请求的消耗在合适的地方

标签:const,检测,window,version,版本,发版,加载,页面
From: https://www.cnblogs.com/coderzdz/p/18135398

相关文章

  • video 分片加载
    API使用:MediaSource+SourceBufferhttpRangeseek进度跳转client.html<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metaname="viewport"content="width=devic......
  • 老年手机打电话页面
    1、对比分析墨刀、Axure、Mockplus等原型设计工具的各自的适用领域及优缺点(至少3条)。2、利用网络资源自学Mockplus或墨刀等原型设计工具,并利用原型工具自拟主题进行原型设计。主题是老年手机打电话页面要求:1)对主题名称、功能、界面设计考虑因素等进行说明;2)每位同学提供至少四......
  • typmorm 类似ef的懒加载
    typmorm类似ef的懒加载在TypeORM中,可以通过设置关系的eager:false属性来实现类似于EntityFrameworkCore(EF)的懒加载功能。这意味着关联的实体将默认不会立即加载,而是在访问它们时才加载。以下是一个简单的例子,演示如何在TypeORM中实现懒加载:  import{Enti......
  • 图片懒加载不完全指南
    图片懒加载不完全指南菜菜菜鸡 1人赞同了该文章图片懒加载在日常开发中,我们常用的两种图片加载方式如下:使用 img 标签加载图片;使用 cssbackground 加载图片。在这篇文章中,您将了解如何延迟加载这两种类型的图像。img标签图片懒加载对......
  • JavaScript判断图片是否已经加载完毕的方法汇总_javascript技巧
    JavaScript判断图片是否已经加载完毕的方法汇总_javascript技巧 在网上有很多关于判断图片是否已经加载完毕的文章,但是有的浏览器并不适合,下面小编给大家分享一些有关JavaScript判断图片是否已经加载完毕方法汇总,具体内容如下所示:一.onload事件通过监听图片的onload事件,可......
  • React.js 网站开发:实现滚动加载动画
    React.js网站开发:实现滚动加载动画极客前端探索者前沿技术的探索者,编码艺术的实践者 最近在开发官网的过程中,涉及到UI动画的制作,其中滚动效果的使用比较频繁,特此整理一下,以便查询和温习。平滑向上过渡动画这种往下滚动过渡渐变显示的动画是最常......
  • HarmonyOS NEXT应用开发案例——滑动页面信息隐藏与组件位移效果
    介绍在很多应用中,向上滑动"我的"页面,页面顶部会有如下变化效果:一部分信息逐渐隐藏,另一部分信息逐渐显示,同时一些组件会进行缩放或者位置移动。向下滑动时则相反。效果图预览使用说明向上滑动页面,出现如下变化:用户名/选择身份/设置图标/客服图标逐渐隐藏,用户头像尺寸逐渐缩小......
  • HarmonyOS NEXT应用开发案例——全屏登录页面
    全屏登录页面介绍本例介绍各种应用登录页面。全屏登录页面:在主页面点击跳转到全屏登录页后,显示全屏模态页面,全屏模态页面从下方滑出并覆盖整个屏幕,模态页面内容自定义,此处分为默认一键登录方式和其他登录方式。效果图预览使用说明点击主页面按钮"点击跳转到全屏登录页",......
  • HarmonyOS NEXT应用开发——Navigation开发 页面切换场景范例
    简介在应用开发时,我们常常遇到,需要在应用内多页面跳转场景时中使用Navigation导航组件做统一的页面跳转管理,它提供了一系列属性方法来设置页面的标题栏、工具栏以及菜单栏的各种展示样式。除此之外还拥有动态加载,navPathStack路由跳转。本文就以Navigation页面切换范例为例,来展......
  • HarmonyOS-基础之页面跳转
    1、配置页面路由信息resources-->base-->profile-->main_pages.json{"src":["pages/demo03/Index","pages/demo03/Detail"]}2、编写页面组件Index.ets/***路由跳转*-使用鸿蒙内置的router*/importrouterfrom'......