如何统计React应用中资源加载、接口请求至数据展示的耗时?
单路由React应用全链路耗时统计方案
首先纠正你的误解:Performance API并没有被废弃,只是早期的performance.timing这类非标准接口被标记为废弃,目前主流浏览器都支持标准的Navigation Timing API Level 2和User Timing API,完全可以用来实现你的需求。
一、统计静态资源(JS/CSS等)加载总耗时
静态资源的加载可以通过PerformanceObserver实时监听,或在页面加载完成后批量获取资源条目计算耗时:
方式1:实时监听资源加载完成
function trackAllResourcesLoaded() { let loadedCount = 0; // 预统计页面初始静态资源总数 const totalResources = document.querySelectorAll('script, link[rel="stylesheet"], img').length; const observer = new PerformanceObserver((list) => { loadedCount += list.getEntries().length; if (loadedCount === totalResources) { const lastResource = list.getEntries().pop(); const totalResourceTime = lastResource.responseEnd - performance.timeOrigin; console.log('所有静态资源加载完成耗时:', `${totalResourceTime}ms`); observer.disconnect(); } }); observer.observe({ entryTypes: ['resource'] }); } // 在应用入口(如index.js)调用 trackAllResourcesLoaded();
方式2:页面加载完成后批量计算
window.addEventListener('load', () => { const resources = performance.getEntriesByType('resource'); // 找到最后一个完成加载的资源时间点 const maxResponseEnd = Math.max(...resources.map(r => r.responseEnd)); const totalResourceTime = maxResponseEnd - performance.timeOrigin; console.log('所有静态资源加载总耗时:', `${totalResourceTime}ms`); });
二、统计API请求的耗时
针对多个API请求,可通过请求库拦截器或PerformanceObserver监听请求事件:
方式1:Axios拦截器标记耗时
import axios from 'axios'; // 请求拦截:记录请求启动时间 axios.interceptors.request.use(config => { config._startTime = performance.now(); return config; }, error => Promise.reject(error)); // 响应拦截:计算并打印请求耗时 axios.interceptors.response.use(response => { const duration = performance.now() - response.config._startTime; console.log(`API ${response.config.url} 耗时: ${duration.toFixed(2)}ms`); return response; }, error => { const duration = performance.now() - error.config._startTime; console.log(`API ${error.config.url} 请求失败耗时: ${duration.toFixed(2)}ms`); return Promise.reject(error); });
方式2:监听所有fetch/XHR请求
const observer = new PerformanceObserver((list) => { list.getEntries().forEach(entry => { if (entry.entryType === 'fetch' || entry.entryType === 'xmlhttprequest') { const duration = entry.responseEnd - entry.requestStart; console.log(`请求 ${entry.name} 耗时: ${duration.toFixed(2)}ms`); } }); }); observer.observe({ entryTypes: ['fetch', 'xmlhttprequest'] });
三、统计从页面启动到数据展示的总耗时
在React组件中,待所有API请求完成、数据渲染完成后,计算从页面初始化到展示的全链路耗时:
import { useEffect, useState } from 'react'; import axios from 'axios'; export default function DataPage() { const [loading, setLoading] = useState(true); const [data, setData] = useState({}); useEffect(() => { const fetchAllData = async () => { try { // 并行发起多个API请求 const [userRes, goodsRes] = await Promise.all([ axios.get('/api/user'), axios.get('/api/goods') ]); setData({ user: userRes.data, goods: goodsRes.data }); setLoading(false); // 计算全链路总耗时 const totalDuration = performance.now() - performance.timeOrigin; console.log('从页面加载到数据展示总耗时:', `${totalDuration.toFixed(2)}ms`); } catch (err) { console.error('数据请求失败:', err); setLoading(false); } }; fetchAllData(); }, []); if (loading) { return <div className="loading">加载中...</div>; } return ( <div className="data-container"> <div>用户信息:{JSON.stringify(data.user)}</div> <div>商品列表:{JSON.stringify(data.goods)}</div> </div> ); }
关键说明
performance.timeOrigin:页面加载的高精度起始时间戳,不受系统时间变更影响performance.now():返回相对于timeOrigin的毫秒数,精度可达微秒级- 若需上报统计数据,直接将计算出的耗时通过接口发送到后端即可
内容的提问来源于stack exchange,提问作者Andrey Rafalskyi
相关产品推荐
相关产品推荐

