在中高级前端面试中,有一个隐藏在“性能优化”、“前端监控”、“埋点系统”背后的常青问题,那就是:
““你有没有设计过请求耗时统计工具?你会怎么统计全站请求的耗时?”
这个问题频率之高,几乎可以和“你会不会节流防抖”一较高下。原因很简单:
因此,这题不只是考察你“会不会写”,更重要的是你“能不能设计”和“是否理解底层机制”。
在日常开发中,我们经常遇到这些场景:
这时,我们就需要一套“全站请求耗时统计工具”来做三件事:
我们常用的请求方式有两种:XMLHttpRequest
和 Fetch
。要实现全站监控,我们要对它们进行“拦截”,也就是重写它们的行为。
const originalFetch = window.fetch;
window.fetch = asyncfunction (...args) {
const start = Date.now();
try {
const response = await originalFetch.apply(this, args);
const end = Date.now();
reportTiming(args[0], end - start); // 上报地址 & 耗时
return response;
} catch (err) {
const end = Date.now();
reportTiming(args[0], end - start, true);
throw err;
}
};
function reportTiming(url, duration, isError = false) {
console.log(`[请求监控] ${url} - ${duration}ms ${isError ? '(失败)' : ''}`);
// TODO: 上报给服务端或监控平台
}
apply(this, args)
保证原有 fetch 的上下文和参数不变;这个方式最适合现代浏览器和新项目,兼容性好,逻辑清晰。对老项目则可能需要兼容 XMLHttpRequest
。
虽然 fetch
已普及,但不少老项目仍大量使用 axios
或 jQuery,这些默认基于 XMLHttpRequest
实现。拦截 XHR
是实现全面覆盖的关键。
const originalXHR = window.XMLHttpRequest;
function wrapXHR() {
const oldOpen = originalXHR.prototype.open;
const oldSend = originalXHR.prototype.send;
originalXHR.prototype.open = function (method, url, async) {
this._url = url;
oldOpen.apply(this, arguments);
};
originalXHR.prototype.send = function (...args) {
const start = Date.now();
this.addEventListener('loadend', () => {
const duration = Date.now() - start;
reportTiming(this._url, duration, this.status >= 400);
});
oldSend.apply(this, args);
};
}
wrapXHR();
open
是为了保存请求地址;send
是为了注入 loadend
事件;因为如果你用 fetch
再去上报耗时信息,会再次触发监控逻辑,造成死循环。
navigator.sendBeacon
function reportTiming(url, duration, isError = false) {
const data = {
url,
duration,
status: isError ? 'error' : 'ok',
timestamp: Date.now(),
};
const blob = new Blob([JSON.stringify(data)], { type: 'application/json' });
navigator.sendBeacon('/monitor/collect', blob);
}
如果你的项目在使用日志采集工具(如 Sentry、阿里云前端监控),可将 reportTiming
接入这些 SDK 的 track
接口中。
如果你希望更进一步,可以考虑这些优化:
这些扩展都能显著提升系统监控粒度与可用性,属于高阶加分项。
这套系统可作为前端性能监控的基础设施,对日常调优和故障定位都非常有帮助。
面试时不要直接说“我用了 axios 的拦截器”就完了,那太表层了。正确的答题思路应该是:
sendBeacon
的优势、上报节流策略、打点格式。“如果你认真理解并实践过这套方案,恭喜你已经具备了架构思维中的“全局拦截 + 数据打点 + 安全上报”三件套能力。这不只是一道题,而是一种工程师的职业素养。
保持学习、保持深度,面试问题就会变成你炫技的舞台。
欢迎大家访问我们的刷题网站(https://fe.ecool.fun/)或者小程序 前端面试题宝典 进行刷题,1200多道全网最全的前端面试题,让你一网打尽。
有会员购买、辅导咨询的小伙伴,可以通过下面的二维码,联系我们的小助手。