使用 js 和 Beacon API 实现一个简易版的前端埋点监控 npm 包
阅读原文时间:2021年05月24日阅读:1

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

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

https://caniuse.com/beacon

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

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

    "use strict";

    /**
    *

    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); // Lets 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 Candidate Recommendation 13 April 2017

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

W3C Editor's Draft 30 January 2020

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

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

KOA server

React client

WebSocket

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\n';
});

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

document.addEventListener('DOMContentLoaded', (event) => {
    log.textContent = log.textContent + `DOMContentLoaded\n`;
});

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);

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

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 发布文章使用:只允许注册用户才可以访问!