整体架构设计
项目地址【部分代码】
注意点:
1.xhr “重写”
import { dispatch } from "../event";
import { AJAX_RESPONSE_TIME, AJAX_STATUS_ERROR } from "../listen/type";
const xhrMdifiy = (
options = {
witheList: [],
}
) => {
// 全局变量
const win = window;
// 标准ajax
const XMLHttpRequest = win.XMLHttpRequest;
// fetch
const fetch = win.fetch;
//out XML
const OutXMLHttpRequest = function () {
const startTime = Date.now();
const xhr = new XMLHttpRequest();
const self = this;
const readystatechangeEvent = [];
const onerrorEvent = [];
let body = null;
const rHeaders = [];
let type = '';
const catchNormalRequestStatus = function (e) {
const { currentTarget } = e;
const { response, responseURL } = currentTarget;
const endTime = Date.now();
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
let diffTime = endTime - startTime;
dispatch(AJAX_RESPONSE_TIME, diffTime);
} else {
const requestHeaders = rHeaders.reduce((p, q) => {
return {
...p,
[q[0]]: q[1],
};
}, {});
if (typeof body === "string") {
body = body;
}
if (body instanceof FormData) {
const bCopy = {};
for (let pair of formData.entries()) {
if (bCopy[1] instanceof Blob) {
bCopy[pair[0]] = {
fileName: bCopy[1].fileName,
size: bCopy[1].size,
};
} else {
bCopy[pair[0]] = pair[1];
}
}
}
if (body instanceof Blob) {
const bCopy = {};
bCopy = {
fileName: body.fileName,
size: body.size,
};
}
if (body instanceof Object) {
body = JSON.stringify(body);
}
const postData = {
type,
body,
response,
responseURL,
requestHeaders,
}
console.log(postData)
dispatch(AJAX_STATUS_ERROR, postData);
}
}
};
//
readystatechangeEvent.push(catchNormalRequestStatus);
// 代理 xhr 对象
for (let key in xhr) {
if (["setRequestHeader", "send", 'open'].includes(key)) {
continue;
}
Object.defineProperty(self, key, {
get() {
if (typeof xhr[key] === "function") {
return xhr[key].bind(xhr);
}
return xhr[key];
},
set(arg) {
switch (key) {
case "onreadystatechange": {
const fn = arg;
fn && readystatechangeEvent.push(fn);
break;
}
default: {
xhr[key] = arg;
}
}
},
});
}
// 重写 为了获取 请求类型
self.open = function (...arg) {
type = arg[0]
xhr.open.apply(xhr, arg)
}
// 重写为了获取 发送数据
self.send = function (data) {
body = data;
xhr.send(data);
};
self.setRequestHeader = function (...arg) {
rHeaders.push(arg);
xhr.setRequestHeader(...arg);
};
// 检查状态变更 【默认注入一个监听事件】
xhr.onreadystatechange = function (e) {
readystatechangeEvent.forEach((fn) => {
if (typeof fn === "function") {
fn.call(xhr, e);
}
});
};
return self;
};
win.XMLHttpRequest = OutXMLHttpRequest;
};
export default xhrMdifiy;
2.资源加载 及 代码报错
import { LOAD_SOURCE_ERROR, SCRIPT_EXECUTE_ERROR } from "../listen/type";
import { dispatch, on } from "../event";
import { event } from "@l6zt/cutils";
const win = window;
const doc = window.document;
/*
处理文件资源加载报错 标签中必须有【crossorigin="anonymous"】
<script src="xx" crossorigin="anonymous" ></script>
】
*/
event.on(win, 'error', (e) => {
const { message, filename, lineno, colno, srcElement } = e;
if (filename) {
const payload = {
message,
filename,
lineno,
colno,
}
console.log(payload)
dispatch(SCRIPT_EXECUTE_ERROR, payload);
}
});
// 观察资源加载情况 【观察 docment ”媒体元素“ 插入情况】
const observer = new MutationObserver((mutationsList, observer) => {
mutationsList.forEach((mutation) => {
const { type, addedNodes } = mutation;
if (type === "childList") {
addedNodes.forEach((el) => {
if ( [HTMLScriptElement, HTMLImageElement,HTMLVideoElement, HTMLAudioElement, Image ].find((C) => el instanceof C ) ) {
event.on(el, 'error', (e) => {
const { target } = e;
const payload = {
type: target.localName,
src: target.getAttribute('src') || target.getAttribute('href')
}
console.log(payload)
dispatch(LOAD_SOURCE_ERROR, payload)
})
}
});
}
});
});
observer.observe(doc, { attributes: true, childList: true, subtree: true });
3.性能监控 【例子】
const win = window
win.addEventListener('load', function() {
const perfData = window.performance.timing;
const pageLoadTime = perfData.loadEventEnd - perfData.navigationStart;
const connectTime = perfData.responseEnd - perfData.requestStart;
const renderTime = perfData.domComplete - perfData.domLoading;
});
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。