在前端实现性能 sdk,要求采集首屏性能、完全加载、tti、白屏、卡顿、接口请求耗时等技术指标。
以下是一个前端性能 SDK 的实现方案,包含主要指标的采集逻辑和代码示例:
1. 首屏性能 (First Contentful Paint)
// 监听首屏绘制事件
const observer = new PerformanceObserver((list) => {
const entry = list.getEntries()[0];
console.log('First Contentful Paint:', entry.startTime);
// 上报数据
});
observer.observe({ type: 'paint', buffered: true });
2. 完全加载时间 (Load Event End)
window.addEventListener('load', () => {
const loadTime = performance.now();
console.log('Page Load Time:', loadTime);
});
3. TTI (Time to Interactive)
let isInteractive = false;
let ttiTime = 0;
// 检测用户交互事件
['click', 'touchstart', 'keydown'].forEach(event => {
window.addEventListener(event, () => {
if (!isInteractive) {
ttiTime = performance.now();
isInteractive = true;
console.log('TTI:', ttiTime);
}
});
});
// 检测长任务(>50ms)
const longTaskObserver = new PerformanceObserver((list) => {
const entries = list.getEntries();
entries.forEach(entry => {
if (entry.duration > 50) {
// 重置TTI检测
isInteractive = false;
ttiTime = 0;
}
});
});
longTaskObserver.observe({ entryTypes: ['longtask'] });
4. 白屏时间 (White Screen Duration)
let whiteScreenStart = 0;
// 记录开始时间
const beforeLoad = performance.timing.navigationStart;
whiteScreenStart = beforeLoad;
// 检测首次渲染
const firstRenderObserver = new PerformanceObserver((list) => {
const entry = list.getEntries()[0];
const duration = entry.startTime - whiteScreenStart;
console.log('White Screen Duration:', duration);
});
firstRenderObserver.observe({ type: 'render', buffered: true });
5. 卡顿检测 (FPS Monitoring)
let lastFrameTime = performance.now();
let frameCount = 0;
let isFreezing = false;
function checkFPS() {
const now = performance.now();
const delta = now - lastFrameTime;
lastFrameTime = now;
frameCount++;
if (delta > 16) { // 60fps对应的16ms间隔
if (!isFreezing) {
isFreezing = true;
console.log('页面卡顿开始');
}
} else {
isFreezing = false;
}
// 每秒钟计算一次平均帧率
if (now - lastFrameTime >= 1000) {
const fps = frameCount;
console.log(`Current FPS: ${fps}`);
frameCount = 0;
}
requestAnimationFrame(checkFPS);
}
requestAnimationFrame(checkFPS);
6. 接口请求耗时 (API Monitoring)
// 重写XMLHttpRequest
const nativeXHR = XMLHttpRequest;
XMLHttpRequest = function() {
const xhr = new nativeXHR();
const send = xhr.send;
xhr.send = function(...args) {
const startTime = performance.now();
xhr.addEventListener('load', () => {
const duration = performance.now() - startTime;
console.log(`API ${xhr.url}耗时: ${duration}ms`);
});
send.apply(xhr, args);
};
return xhr;
};
// 监听fetch请求
const nativeFetch = window.fetch;
window.fetch = async (...args) => {
const startTime = performance.now();
const response = await nativeFetch(...args);
const duration = performance.now() - startTime;
console.log(`Fetch ${args[0]}耗时: ${duration}ms`);
return response;
};
7. 数据上报
function sendData(data) {
const body = JSON.stringify(data);
const xhr = new XMLHttpRequest();
xhr.open('POST', '/api/performance', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(body);
}
// 示例上报数据格式
const reportData = {
timestamp: Date.now(),
metrics: {
fcp: 1200,
loadTime: 2500,
tti: 3000,
whiteScreen: 500,
fps: 58,
apiRequests: [
{ url: '/api/data', duration: 350 },
{ url: '/api/config', duration: 120 }
]
}
};
sendData(reportData);
实现要点:
-
性能优化:
- 使用
requestIdleCallback处理非紧急任务 - 数据上报采用
navigator.sendBeacon保证可靠性 - 对监控逻辑进行采样处理(如5%的用户采样)
- 使用
-
兼容性处理:
- 对不支持的API使用polyfill
- 优雅降级处理无法获取的指标
-
用户体验:
- 避免影响主线程性能
- 提供配置开关
- 最小化内存占用
-
扩展能力:
- 支持自定义指标采集
- 可配置的上报规则
- 插件化架构设计
建议结合真实用户监控(RUM)和实验室数据(Lighthouse)进行综合性能分析,持续优化页面加载和交互体验。