乐趣区

关于javascript:历险记-Performance

前端监控 API 时应用了 Performace 接口,然而目前大部分文章都只是列举其自身的属性或办法,实战中应用的场景比拟少,我本人也走了些弯路,当初记录下这些,大家能够一起来探讨下。

先讲一下应用场景,页面加载后记录后盾接口,页面跳转前也记录后盾接口。在记录接口前须要辨别接口是否须要曾经被记录过,不会重复记录。

就如何标记接口数据是否已被记录,本人尝试了四种形式

  1. 对已记录的接口增加 outdate 字段并标记为 true
  2. 应用 performace.mark 办法打标记,每次只记录最初一个标记后的接口
  3. 应用 performace.mark 形式打标记,然而比拟的是比 mark 的 startTime 字段大的 responseEnd 字段 (比拟绕后续看代码吧)
  4. 应用全局变量记录下发送的接口数量,每次先依据变量截取 performace.getEntries() 返回的数组再更新变量的值

1、2 两种形式被淘汰了,3 过后因工夫关系只解决想法阶段,后测试可行,4 是目前采纳的

上面依据形式来讲讲遇到的问题

1、performace 只读

尽管当初大部分的浏览器反对在 PerformaceEntry 中减少字段,但有些浏览器不容许,如 IE 11、chrome 的局部版本,MDN 中目前也是标记为 只读

  const entries = performance.getEntries();
  // 上面办法只筛选了发送的接口,须要过滤掉发送埋点申请的接口
  const freshEntries = entries.filter(
    item =>
      !item.outdate &&
      item.entryType === "resource" &&
      item.initiatorType === "xmlhttprequest"
  );

  entries.forEach(item => {item.outdate = true;});

  return freshEntries || [];

2、打标记

在打标记时已发送申请但未返回数据的接口,会在接口返回后会呈现在标记前。并不会如预期的呈现在标记后,起因是 PerformaceEntry 是依据 startTime 排序的

  const entries = performance.getEntries();
  entries.reverse();

  if (entries[0].entryType === 'mark' && entries[0].name === 'MARKNAME') {return [];
  }

  // 为避免在这期间有接口申请,先打标记再解决数据
  performance.mark('MARKNAME');

  const endIndex = entries.findIndex(i => i.entryType === 'mark' && i.name === 'MARKNAME');

  const freshEntries = entries
    .slice(0, endIndex)
    .filter(item => item.entryType === 'resource' && item.initiatorType === 'xmlhttprequest');

  return freshEntries || [];

3、打标记后比照 mark 工夫和接口返回工夫

间接上代码吧!更简略间接

  const entries = performance.getEntries();

  const markList = performance.getEntriesByName('MARKNAME');
  markList.reverse();
  const markTime = markList.length ? markList[0].startTime : 0;

  // 为避免在这期间有接口申请,先打标记再解决数据
  performance.mark('MARKNAME');

  const freshEntries = entries.filter(
    item =>
      item.entryType === "resource" &&
      item.initiatorType === "xmlhttprequest" &&
      item.responseEnd > markTime // 比照接口的返回工夫和上次打标记的工夫
  );

  return freshEntries || [];

我的项目采纳的是 typeScript,打包时报 Property 'responseEnd' does not exist on type 'PerformanceEntry',对 ts 语法也不是很熟,就先放弃了

4、记录已发送的接口数量

这个形式很简略,之所以一开始的时候未采纳,是不想创立全局变量,还要截取数组,给字段赋值。起初因工夫问题也就只能这样了。

  // 初始化时,alreadySendApiNum 设置为 0 
  const entries = performance.getEntries();

  const freshEntries = entries
    .filter(item => item.entryType === 'resource' && item.initiatorType === 'xmlhttprequest');

  return freshEntries || [];

  freshEntries.slice(alreadySendApiNum)... // 记录接口数据

  alreadySendApiNum = freshEntries.length;

如有侵权请告知

退出移动版