zoukankan      html  css  js  c++  java
  • xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

    使用 js 和 Beacon API 实现一个简易版的前端埋点监控 npm 包

    前端监控,埋点,数据收集,性能监控

    Beacon API

    https://caniuse.com/beacon

    1. 优点,请求发送是非阻塞的 post ,用户体验好;支持多种数据格式;

    2. 缺点,IE 不支持,使用 XHR 作为 fallback 方案

    "use strict";
    
    /**
     *
     * @author xgqfrms
     * @license MIT
     * @copyright xgqfrms
     * @created 2020-01-01
     * @modified
     *
     * @description
     * @difficulty Easy Medium Hard
     * @complexity O(n)
     * @augments
     * @example
     * @link
     * @solutions
     *
     * @best_solutions
     *
     */
    
    const log = console.log;
    
    let startTime = performance.now();
    
    window.addEventListener(`load`, (e) => {
      log(`window load`);
      log(`page is fully loaded`);
    });
    
    window.addEventListener(`DOMContentLoaded`, (e) => {
      log(`window DOMContentLoaded`);
      // log(`DOM fully loaded and parsed`);
    });
    
    const logVisit = (url = ``) => {
      // Test that we have support
      if (!navigator.sendBeacon) {
        // XHR fallback
        return true;
      } else {
      // URL to send the data to, e.g.
      // let url = `/api/log`;
      // Data to send
      let data = new FormData();
      data.append(`start`, startTime);
      data.append(`end`, performance.now());
      data.append(`url`, document.URL);
      // Let`s go!
      navigator.sendBeacon(url, data);
      }
    };
    
    // 将日志记录封装到一个函数中,则可以在页面卸载时调用它。
      // ✅ good place for sendBeacon ???
    
    window.addEventListener(`beforeunload`, (e) => {
      log(`window beforeunload`);
      // ❌ bad place for sendBeacon
      logVisit(`/api/log`);
    });
    
    window.addEventListener(`unload`, (e) => {
      log(`window unload`);
      // ❌ bad place for sendBeacon
      // logVisit(`/api/log`);
    });
    
    
    // navigator.sendBeacon(`https://www.xgqfrms.xyz/`, `hello ✅`);
    
    
    

    W3C & Beacon

    W3C Candidate Recommendation 13 April 2017

    https://www.w3.org/TR/beacon/

    W3C Editor's Draft 30 January 2020

    https://w3c.github.io/beacon/

    
    
    

    demos

    
    
    
    
    
    

    test

    异常关闭浏览器窗口(强制退出 Chrome 进程),验证请求是否会发送成功?

    KOA server

    React client

    WebSocket

    load & DOMContentLoaded

    https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event

    https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event

    readystate: interactive
    DOMContentLoaded
    readystate: complete
    load

    window.addEventListener('load', (event) => {
        log.textContent = log.textContent + 'load
    ';
    });
    
    document.addEventListener('readystatechange', (event) => {
        log.textContent = log.textContent + `readystate: ${document.readyState}
    `;
    });
    
    document.addEventListener('DOMContentLoaded', (event) => {
        log.textContent = log.textContent + `DOMContentLoaded
    `;
    });
    
    
    
    

    visibilitychange & pagehide

    https://developer.mozilla.org/en-US/docs/Web/API/Document/visibilitychange_event

    "use strict";
    
    /**
     *
     * @author xgqfrms
     * @license MIT
     * @copyright xgqfrms
     * @created 2020-11-11
     * @modified
     *
     * @description
     * @difficulty Easy Medium Hard
     * @complexity O(n)
     * @augments
     * @example
     * @link
     * @solutions
     *
     * @best_solutions
     *
     */
    
    const log = console.log;
    
    let startTime = performance.now();
    
    window.addEventListener(`load`, (e) => {
      log(`window load`);
      log(`page is fully loaded`);
    });
    
    window.addEventListener(`DOMContentLoaded`, (e) => {
      log(`window DOMContentLoaded`);
      // log(`DOM fully loaded and parsed`);
    });
    
    const logVisit = (url = ``) => {
      // Test that we have support
      if (!navigator.sendBeacon) {
        // XHR fallback
        return true;
      } else {
      // URL to send the data to, e.g.
      // let url = `/api/log`;
      // Data to send
      let data = new FormData();
      data.append(`start`, startTime);
      data.append(`end`, performance.now());
      data.append(`url`, document.URL);
      // Let`s go!
      navigator.sendBeacon(url, data);
      }
    };
    
    // 将日志记录封装到一个函数中,则可以在页面卸载时调用它。
    window.addEventListener(`pagehide`, (e) => {
      log(`window beforeunload`);
      // ✅ good place for sendBeacon
      logVisit(`/api/log`);
      if (event.persisted) {
        /* the page isn't being discarded, so it can be reused later */
      }
    }, false);
    
    
    
    document.addEventListener(`visibilitychange`, (e) => {
    // window.addEventListener(`visibilitychange`, (e) => {
      log(`document.visibilityState`, document.visibilityState);
      // if (document.visibilityState === `hidden`) {
      // if (document.visibilityState === `visible`) {
      //   backgroundMusic.play();
      // } else {
      //   backgroundMusic.pause();
      // }
      // log(`window visibilitychange`);
      // ✅ good place for sendBeacon
      logVisit(`/api/log`);
    });
    
    
    
    window.addEventListener(`beforeunload`, (e) => {
      log(`window beforeunload`);
      // ❌ bad place for sendBeacon
      // logVisit(`/api/log`);
    });
    
    window.addEventListener(`unload`, (e) => {
      log(`window unload`);
      // ❌ bad place for sendBeacon
      // logVisit(`/api/log`);
    });
    
    
    // navigator.sendBeacon(`https://www.xgqfrms.xyz/`, `hello ✅`);
    
    
    

    https://developer.mozilla.org/en-US/docs/Web/API/Window/pagehide_event

    
    window.addEventListener("pagehide", event => {
      if (event.persisted) {
        /* the page isn't being discarded, so it can be reused later */
      }
    }, false);
    
    

    beforeunload & unload

    https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event

    window.addEventListener('beforeunload', (event) => {
      // Cancel the event as stated by the standard.
      event.preventDefault();
      // Older browsers supported custom message
      event.returnValue = '';
    });
    
    

    https://developer.mozilla.org/en-US/docs/Web/API/Window/unload_event

    refs

    MDN

    https://developer.mozilla.org/en-US/docs/Web/API/Beacon_API

    https://developer.mozilla.org/en-US/docs/Glossary/beacon

    https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon



    ©xgqfrms 2012-2020

    www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!


  • 相关阅读:
    ndoejs解析req,伪造http请求
    ndoejs创建多重文件夹
    路径path的正则通配符-nodejs
    例题1.5 快速排序
    例题1.3 整数划分问题
    sdcf day4 qaq模拟赛总结
    P1168 中位数
    浅谈LCA
    sdcf day1 qwq比赛题解
    2019山东夏令营划水记
  • 原文地址:https://www.cnblogs.com/xgqfrms/p/13954019.html
Copyright © 2011-2022 走看看