前端监控 API 时应用了 Performace 接口,然而目前大部分文章都只是列举其自身的属性或办法,实战中应用的场景比拟少,我本人也走了些弯路,当初记录下这些,大家能够一起来探讨下。
先讲一下应用场景,页面加载后记录后盾接口,页面跳转前也记录后盾接口。在记录接口前须要辨别接口是否须要曾经被记录过,不会重复记录。
就如何标记接口数据是否已被记录,本人尝试了四种形式
- 对已记录的接口增加 outdate 字段并标记为 true
- 应用 performace.mark 办法打标记,每次只记录最初一个标记后的接口
- 应用 performace.mark 形式打标记,然而比拟的是比 mark 的 startTime 字段大的 responseEnd 字段 (比拟绕后续看代码吧)
- 应用全局变量记录下发送的接口数量,每次先依据变量截取 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;
如有侵权请告知