You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何统计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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 09:51:17