zoukankan      html  css  js  c++  java
  • 前端性能和错误监控

    本地缓存在localStorage中的监控对象

    export default function monitorInit(timeout = 7 * 24 * 60 * 60) {
      let whiteScreen = new Date() - performance.timing.navigationStart;
      const monitor = {
        // 数据上传地址
        // url: '',
        // 性能信息
        performance: {},
        // 资源信息
        resources: {},
        // 错误信息
        errors: {},
    
        // 用户信息
        client: {
          // 屏幕宽度
          screen: screen.width,
          // 屏幕高度
          height: screen.height,
          // 浏览器平台
          platform: navigator.platform,
          // 浏览器的用户代理信息
          userAgent: navigator.userAgent,
          // 浏览器用户界面的语言
          language: navigator.language
        },
        cacheTime: new Date().getTime(),
        timeout: timeout
        // 手动添加错误
        // addError(error) {
        //   const obj = {};
        //   const { type, msg, url, row, col } = error;
        //   if (type) obj.type = type;
        //   if (msg) obj.msg = msg;
        //   if (url) obj.url = url;
        //   if (row) obj.row = row;
        //   if (col) obj.col = col;
        //   obj.time = new Date().getTime();
        //   monitor.errors.push(obj);
        // },
        // 重置 monitor 对象
        // reset() {
        //   window.performance && window.performance.clearResourceTimings();
        //   monitor.performance = getPerformance();
        //   monitor.resources = getResources();
        //   monitor.errors = {};
        // },
        // 清空 error 信息
        // clearError() {
        //   monitor.errors = {};
        // },
        // 上传监控数据
        // upload() {
        // 自定义上传
        // axios.post({
        //     url: monitor.url,
        //     data: {
        //         performance,
        //         resources,
        //         errors,
        //         user,
        //     }
        // })
        // },
        // 设置数据上传地址
        // setURL(url) {
        //   monitor.url = url;
        // }
      };
    
      const getMonitor = () => {
        isOverTime();
        return JSON.parse(localStorage.getItem('monitor'));
      };
    
      const isOverTime = () => {
        const data = JSON.parse(localStorage.getItem('monitor'));
    
        // 没有数据 一定超时
        if (!data) {
          return true;
        }
        // 获取系统当前时间戳
        const currentTime = new Date().getTime();
        // 获取当前时间与存储时间的过去的秒数
        const overTime = (currentTime - data.cacheTime) / 1000;
        // console.log(overTime);
        // 如果过去的秒数大于当前的超时时间,也返回null让其去服务端取数据
        if (overTime > data.timeout) {
          localStorage.removeItem('monitor');
          return true;
        }
        return false;
      };
      // 获取性能信息
      const getPerformance = () => {
        if (!window.performance) return;
        const timing = window.performance.timing;
        const performance = {
          // 重定向耗时
          redirect: timing.redirectEnd - timing.redirectStart,
          // 白屏时间
          whiteScreen: whiteScreen,
          // DOM 渲染耗时
          dom: timing.domComplete - timing.domLoading,
          // 页面加载耗时
          load: timing.loadEventEnd - timing.navigationStart,
          // 页面卸载耗时
          unload: timing.unloadEventEnd - timing.unloadEventStart,
          // 请求耗时
          request: timing.responseEnd - timing.requestStart,
          // 获取性能信息时当前时间
          time: new Date().getTime()
        };
    
        return performance;
      };
    
      // 获取资源信息
      const getResources = () => {
        if (!window.performance) return;
        const data = window.performance.getEntriesByType('resource');
        const resource = {
          xmlhttprequest: [],
          css: [],
          other: [],
          script: [],
          img: [],
          link: [],
          fetch: [],
          // 获取资源信息时当前时间
          time: new Date().getTime()
        };
    
        data.forEach(item => {
          const arry = resource[item.initiatorType];
          arry &&
            arry.push({
              // 资源的名称
              name: item.name,
              // 资源加载耗时
              duration: item.duration.toFixed(2),
              // 资源大小
              size: item.transferSize,
              // 资源所用协议
              protocol: item.nextHopProtocol
            });
        });
    
        return resource;
      };
    
      window.onload = () => {
        // 在浏览器空闲时间获取性能及资源信息 https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestIdleCallback
        let monitorObj = getMonitor() ? getMonitor() : monitor;
        if (window.requestIdleCallback) {
          window.requestIdleCallback(() => {
            monitorObj.performance = getPerformance();
            // console.log('页面性能信息');
            // console.log(monitor.performance);
            monitorObj.resources = getResources();
            // console.log('页面资源信息');
            // console.log(monitor.resources);
            localStorage.setItem('monitor', JSON.stringify(monitorObj));
          });
        } else {
          setTimeout(() => {
            monitor.performance = getPerformance();
            // console.log('页面性能信息');
            // console.log(monitor.performance);
            monitor.resources = getResources();
            // console.log('页面资源信息');
            // console.log(monitor.resources);
            localStorage.setItem('monitor', JSON.stringify(monitor));
          }, 0);
        }
      };
    
      // 捕获资源加载失败错误 js css img...
      addEventListener(
        'error',
        e => {
          const target = e.target;
    
          if (target !== window) {
            let monitorObj = getMonitor() ? getMonitor() : monitor;
            let url = target.src || target.href;
            if (!monitorObj.errors[url]) {
              monitorObj.errors[url] = {
                type: target.localName,
                url: url,
                msg: (target.src || target.href) + ' is load error',
                // 错误发生的时间
                time: new Date().getTime()
              };
              localStorage.setItem('monitor', JSON.stringify(monitorObj));
              // console.log('所有的错误信息');
              // console.log(monitor.errors);
            }
          }
        },
        true
      );
    
      // 监听 js 错误
      window.onerror = function(msg, url, row, col, error) {
        let monitorObj = getMonitor() ? getMonitor() : monitor;
        let key = `${url}:${row}`;
        if (!monitorObj.errors[key]) {
          monitorObj.errors[key] = {
            type: 'javascript', // 错误类型
            row: row, // 发生错误时的代码行数
            col: col, // 发生错误时的代码列数
            msg: error && error.stack ? error.stack : msg, // 错误信息
            url: url, // 错误文件
            time: new Date().getTime() // 错误发生的时间
            // console.log('所有的错误信息');
            // console.log(monitor.errors);
          };
          localStorage.setItem('monitor', JSON.stringify(monitorObj));
        }
      };
    
      // 监听 promise 错误 缺点是获取不到行数数据
      addEventListener('unhandledrejection', e => {
        let monitorObj = getMonitor() ? getMonitor() : monitor;
        let msg = (e.reason && e.reason.msg) || e.reason || '';
        if (!monitorObj.errors[msg]) {
          monitorObj.errors[msg] = {
            type: 'promise',
            msg: msg,
            // 错误发生的时间
            time: new Date().getTime()
          };
          // console.log('所有的错误信息');
          // console.log(monitor.errors);
          localStorage.setItem('monitor', JSON.stringify(monitorObj));
        }
      });
    
      return monitor;
    }

     

    前端性能和错误监控

    前端异常监控解决方案研究

  • 相关阅读:
    ACwing(基础)--- 01背包和完全背包、多重背包问题
    Python --- 实战一
    Python --- 正则表达式
    Python --- 网络爬虫
    Python --- 异常处理
    Python --- 文件操作
    Python --- 模块
    Python --- 基础语法
    securecrt颜色设置
    Tomcat启动排查
  • 原文地址:https://www.cnblogs.com/ziyoublog/p/14764259.html
Copyright © 2011-2022 走看看