← 返回目录

第 6 卷

第 6 / 13 卷日期:

• 异步数据请求监控:SPA 依赖接口数据渲染页面,需拦截全局异步请求(Axios、Fetch),捕获请

求错误、记录请求耗时,同时关联路由信息,便于定位“某页面某接口”的性能问题。

• 示例(Axios 拦截器):

Code block

1// Axios 请求拦截器:记录请求开始时间

2axios.interceptors.request.use(config => {
3config.__startTime = Date.now();
4config.__routePath = router.currentRoute.path; //关联当前路由
5return config;
6});

7 8// Axios 响应拦截器:捕获错误、计算耗时

9axios.interceptors.response.use( 10response => {

11const requestTime = Date.now() - response.config.__startTime;
12reportPerformanceToServer({
13type: 'spaApiPerformance',
14apiUrl: response.config.url,
15routePath: response.config.__routePath,
16requestTime,
17status: response.status,
18timestamp: Date.now()
19});
20return response;
21},
22error => {
23const errorInfo = {
24type: 'spaApiError',
25apiUrl: error.config?.url,
26routePath: error.config?.__routePath,
27message: error.message,
28status: error.response?.status,
29timestamp: Date.now()
30};
31reportErrorToServer(errorInfo);
32return Promise.reject(error);
33}
34);

• 内存使用监控:通过 window.performance.memory 定期采集内存占用数据,结合路由切换

次数,监控内存是否持续增长(若切换同一路由多次后内存明显上升,大概率存在泄漏)。

• 示例:

Code block

1// 定期采集内存数据,路由切换时额外采集

2let memoryCheckTimer = setInterval(() => {
3if (window.performance?.memory) {
4const memoryInfo = {
5type: 'spaMemoryUsage',
6routePath: router.currentRoute.path,
7usedJSHeapSize: window.performance.memory.usedJSHeapSize, //已使用堆内存
8totalJSHeapSize: window.performance.memory.totalJSHeapSize, //总堆内存
9timestamp: Date.now()
10};
11reportPerformanceToServer(memoryInfo);
12}
13}, 30000); //每30秒采集一次

14 15// 页面卸载时清除定时器

16window.addEventListener('beforeunload', () => {
17clearInterval(memoryCheckTimer);
18});

• 长任务与卡顿监控:SPA 复杂组件渲染、大数据处理易产生长任务,导致页面卡顿,需通过

PerformanceObserver 监听长任务,关联路由和组件信息,精准定位卡顿来源。

4. 状态管理相关错误监控

SPA 多使用 Vuex、Redux 等状态管理库,状态变更错误(如非法状态修改、状态依赖错误)会导致全局功能异常,需针对性监控:

• 状态变更日志与错误捕获:在状态管理的 mutation/action 中添加日志记录和错误捕获,监控非法

状态变更、异步 action 错误等。

• 示例(Vuex):

Code block

1const store = new Vuex.Store({

8// 记录状态变更日志 9reportBehaviorToServer({

10type: 'spaStoreMutation', 11mutationType: type,

12payload: JSON.stringify(payload),
13routePath: router.currentRoute.path,
14timestamp: Date.now()
15});
16} catch (error) {
17const errorInfo = {
18type: 'spaStoreError',
19errorType: 'mutationError',
20mutationType: type,
21payload: JSON.stringify(payload),
22message: error.message,
23stack: error.stack,
24timestamp: Date.now()
25};
26reportErrorToServer(errorInfo);
27throw error;
28}
29}
30 },
31 actions: {
32//异步action错误捕获
33async fetchData({ commit }, payload) {
34try {
35const data = await api.fetchData(payload);
36commit('SET_DATA', data);
37} catch (error) {
38const errorInfo = {
39type: 'spaStoreError',
40errorType: 'actionError',
41actionName: 'fetchData',
42payload: JSON.stringify(payload),
43message: error.message,
44timestamp: Date.now()
45};
46reportErrorToServer(errorInfo);
47throw error;
48}
49}
全站分卷索引 · 13 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷
  8. 8第 8 卷
  9. 9第 9 卷
  10. 10第 10 卷
  11. 11第 11 卷
  12. 12第 12 卷
  13. 13第 13 卷