import tracker from “…/util/tracker”;
export function injectXHR() {
let XMLHttpRequest = window.XMLHttpRequest;
let oldOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function (
method,
url,
async,
username,
password
) {
// 上报的接口不用处理
if (!url.match(/logstores/) && !url.match(/sockjs/)) {
this.logData = {
method,
url,
async,
username,
password,
};
}
return oldOpen.apply(this, arguments);
};
let oldSend = XMLHttpRequest.prototype.send;
let start;
XMLHttpRequest.prototype.send = function (body) {
if (this.logData) {
start = Date.now();
let handler = (type) => (event) => {
let duration = Date.now() - start;
let status = this.status;
let statusText = this.statusText;
tracker.send({
//未捕获的promise错误
kind: “stability”, //稳定性指标
type: “xhr”, //xhr
eventType: type, //load error abort
pathname: this.logData.url, //接口的url地址
status: status + “-” + statusText,
duration: “” + duration, //接口耗时
response: this.response ? JSON.stringify(this.response) : “”,
params: body || “”,
});
};
this.addEventListener(“load”, handler(“load”), false);
this.addEventListener(“error”, handler(“error”), false);
this.addEventListener(“abort”, handler(“abort”), false);
}
oldSend.apply(this, arguments);
};
}
4.4 白屏
- 白屏就是页面上什么都没有
4.4.1 数据设计
{
“title”: “前端监控系统”,
“url”: “http://localhost:8080/”,
“timestamp”: “1590822618759”,
“userAgent”: “chrome”,
“kind”: “stability”, //大类
“type”: “blank”, //小类
“emptyPoints”: “0”, //空白点
“screen”: “2049x1152”, //分辨率
“viewPoint”: “2048x994”, //视口
“selector”: “HTML BODY #container” //选择器
}
4.4.2 实现
-
elementsFromPoint[1]方法可以获取到当前视口内指定坐标处,由里到外排列的所有元素
-
根据 elementsFromPoint api,获取屏幕水平中线和竖直中线所在的元素
import tracker from “…/util/tracker”;
import onload from “…/util/onload”;
function getSelector(element) {
var selector;
if (element.id) {
selector = #${element.id}
;
} else if (element.className && typeof element.className === “string”) {
selector =
“.” +
element.className
.split(" ")
.filter(function (item) {
return !!item;
})
.join(“.”);
} else {
selector = element.nodeName.toLowerCase();
}
return selector;
}
export function blankScreen() {
const wrapperSelectors = [“body”, “html”, “#container”, “.content”];
let emptyPoints = 0;
function isWrapper(element) {
let selector = getSelector(element);
if (wrapperSelectors.indexOf(selector) >= 0) {
emptyPoints++;
}
}
onload(function () {
let xElements, yElements;
debugger;
for (let i = 1; i <= 9; i++) {
xElements = document.elementsFromPoint(
(window.innerWidth * i) / 10,
window.innerHeight / 2
);
yElements = document.elementsFromPoint(
window.innerWidth / 2,
(window.innerHeight * i) / 10
);
isWrapper(xElements[0]);
isWrapper(yElements[0]);
}
if (emptyPoints >= 0) {
let centerElements = document.elementsFromPoint(
window.innerWidth / 2,
window.innerHeight / 2
);
tracker.send({
kind: “stability”,
type: “blank”,
emptyPoints: “” + emptyPoints,
screen: window.screen.width + “x” + window.screen.height,
viewPoint: window.innerWidth + “x” + window.innerHeight,
selector: getSelector(centerElements[0]),
});
}
});
}
//screen.width 屏幕的宽度 screen.height 屏幕的高度
//window.innerWidth 去除工具条与滚动条的窗口宽度 window.innerHeight 去除工具条与滚动条的窗口高度
4.5 加载时间
-
PerformanceTiming[2]
-
DOMContentLoaded[3]
-
FMP[4]
4.5.1 阶段含义
image.png
| 字段 | 含义 |
| — | — |
| navigationStart | 初始化页面,在同一个浏览器上下文中前一个页面unload的时间戳,如果没有前一个页面的unload,则与fetchStart值相等 |
| redirectStart | 第一个HTTP重定向发生的时间,有跳转且是同域的重定向,否则为0 |
| redirectEnd | 最后一个重定向完成时的时间,否则为0 |
| fetchStart | 浏览器准备好使用http请求获取文档的时间,这发生在检查缓存之前 |
| do