aurora blog
  • JS

    • 基本汇总
    • Date时间
    • Array方法
    • String 方法
    • Object方法
    • RegExp正则
    • Es6 新特性等
    • Event-Loop
    • Http and Https
    • for in和for of区别
    • Web Worker
    • Promise && async
    • 堆内存 & 栈内存
    • JS设计模式探索
    • npm & yarn
    • Fetch和Axios的区别
    • 学习及面试问题整理
    • URL 输入到页面加载过程
    • 跨域&nginx本地项目代理
  • FE框架

    • react

      • 基本用法
      • react生命周期
      • hooks 16.8版本后
      • Route原理
      • Redux源码解析
      • React16 Fiber
      • React-VirtualDOM
      • React事件委托机制
      • React性能优化
      • 状态管理方案对比
      • React 18新特性
    • vue

      • vue 基本用法
      • vue 生命周期
      • VirtualDOM
      • vue 事件委托
      • vue 架构
      • vue 状态管理
      • 问题等
    • React-Native

      • React-Native 基本用法
    • 微前端

      • 遇到的问题
    • 鸿蒙 harmony

      • harmony 基础
  • 构建工具

    • webpack

      • Webpack配置详解
      • Webpack的使用
      • Babel-polyfill
      • webpack面试题
    • vite

      • vite配置详解
      • vite面试题
    • rollup

      • Rollup配置详解
      • rollup面试题
    • 构建工具对比
  • 性能优化

    • 性能优化策略
    • 缓存策略
    • 性能优化面试题
  • 浏览器

    • 浏览器渲染原理
    • 浏览器缓存机制
    • 浏览器面试题
  • 工程化

    • 代码规范
    • 工程化面试题
  • 前端安全

    • XSS 攻击与防护
    • CSRF 攻击与防护
    • 前端安全面试题
  • 移动端开发

    • 移动端适配
    • 移动端开发面试题
  • 前端监控

    • 错误监控
    • 性能监控
    • 前端监控面试题
  • Typescript

    • Typescript详解
  • Servers

    • Nodejs
    • Nginx
  • Git命令

    • git常用规范
  • 数据库

    • mongodb
    • mongodb
  • Other

    • Jenkins自动化部署

性能监控

  • 性能监控概述
  • Web Vitals
    • Core Web Vitals
    • 测量 Web Vitals
  • Performance API
    • Navigation Timing
    • Resource Timing
    • Performance Observer
  • 自定义指标
    • 页面加载时间
    • 首屏时间
    • 接口响应时间
  • 性能上报
    • 基础上报
    • 批量上报
  • 性能分析
    • 1. 性能统计
    • 2. 性能趋势
    • 3. 性能优化建议
  • 监控平台
    • 1. Google Analytics
    • 2. 自建监控
  • 最佳实践
    • 1. 指标采集
    • 2. 上报策略
    • 3. 性能分析
    • 4. 告警机制

性能监控概述

前端性能监控是优化用户体验的重要手段,主要包括:

  • 性能指标:Web Vitals、自定义指标
  • 性能采集:Performance API
  • 性能分析:统计、可视化、优化建议

Web Vitals

Core Web Vitals

1. LCP (Largest Contentful Paint)

  • 定义:最大内容绘制时间
  • 目标:< 2.5s
  • 测量:最大可见元素的渲染时间

2. FID (First Input Delay)

  • 定义:首次输入延迟
  • 目标:< 100ms
  • 测量:用户首次交互到浏览器响应的时间

3. CLS (Cumulative Layout Shift)

  • 定义:累积布局偏移
  • 目标:< 0.1
  • 测量:页面布局不稳定的程度

测量 Web Vitals

LCP:

new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const lastEntry = entries[entries.length - 1];
  
  const lcp = lastEntry.renderTime || lastEntry.loadTime;
  console.log('LCP:', lcp);
  
  // 上报
  reportMetric('LCP', lcp);
}).observe({ entryTypes: ['largest-contentful-paint'] });

FID:

new PerformanceObserver((list) => {
  list.getEntries().forEach(entry => {
    const fid = entry.processingStart - entry.startTime;
    console.log('FID:', fid);
    
    // 上报
    reportMetric('FID', fid);
  });
}).observe({ entryTypes: ['first-input'] });

CLS:

let clsValue = 0;
let clsEntries = [];

new PerformanceObserver((list) => {
  list.getEntries().forEach(entry => {
    if (!entry.hadRecentInput) {
      clsValue += entry.value;
      clsEntries.push(entry);
    }
  });
  
  // 上报
  reportMetric('CLS', clsValue);
}).observe({ entryTypes: ['layout-shift'] });

Performance API

Navigation Timing

时间点:

const timing = performance.timing;

const metrics = {
  // DNS 查询时间
  dns: timing.domainLookupEnd - timing.domainLookupStart,
  
  // TCP 连接时间
  tcp: timing.connectEnd - timing.connectStart,
  
  // 请求响应时间
  request: timing.responseEnd - timing.requestStart,
  
  // DOM 解析时间
  domParse: timing.domInteractive - timing.responseEnd,
  
  // 资源加载时间
  resourceLoad: timing.loadEventEnd - timing.domContentLoadedEventEnd,
  
  // 页面加载时间
  pageLoad: timing.loadEventEnd - timing.navigationStart,
  
  // 首字节时间
  ttfb: timing.responseStart - timing.requestStart,
};

Resource Timing

资源加载时间:

performance.getEntriesByType('resource').forEach(resource => {
  const metrics = {
    name: resource.name,
    duration: resource.duration,
    size: resource.transferSize,
    type: resource.initiatorType,
    
    // DNS 时间
    dns: resource.domainLookupEnd - resource.domainLookupStart,
    
    // TCP 时间
    tcp: resource.connectEnd - resource.connectStart,
    
    // 请求时间
    request: resource.responseStart - resource.requestStart,
    
    // 响应时间
    response: resource.responseEnd - resource.responseStart,
  };
  
  // 上报慢资源
  if (metrics.duration > 1000) {
    reportSlowResource(metrics);
  }
});

Performance Observer

监听性能指标:

// 监听所有性能条目
const observer = new PerformanceObserver((list) => {
  list.getEntries().forEach(entry => {
    console.log(entry.name, entry.duration);
  });
});

observer.observe({ 
  entryTypes: ['navigation', 'resource', 'paint', 'measure'] 
});

自定义指标

页面加载时间

window.addEventListener('load', () => {
  const loadTime = performance.timing.loadEventEnd - performance.timing.navigationStart;
  reportMetric('pageLoad', loadTime);
});

首屏时间

function getFirstScreenTime() {
  return new Promise((resolve) => {
    const observer = new PerformanceObserver((list) => {
      const entries = list.getEntries();
      const firstScreenEntry = entries.find(entry => 
        entry.name.includes('first-screen')
      );
      
      if (firstScreenEntry) {
        resolve(firstScreenEntry.duration);
        observer.disconnect();
      }
    });
    
    observer.observe({ entryTypes: ['measure'] });
    
    // 标记首屏
    performance.mark('first-screen-start');
    
    // 首屏渲染完成后
    setTimeout(() => {
      performance.mark('first-screen-end');
      performance.measure('first-screen', 'first-screen-start', 'first-screen-end');
    }, 0);
  });
}

接口响应时间

// 封装 fetch
const originalFetch = window.fetch;

window.fetch = function(...args) {
  const startTime = performance.now();
  
  return originalFetch.apply(this, args)
    .then(response => {
      const duration = performance.now() - startTime;
      
      reportMetric('api', {
        url: args[0],
        duration,
        status: response.status,
      });
      
      return response;
    });
};

性能上报

基础上报

function reportMetric(name, value, tags = {}) {
  const data = {
    name,
    value,
    tags: {
      ...tags,
      url: window.location.href,
      userAgent: navigator.userAgent,
      timestamp: Date.now(),
    },
  };
  
  // 使用 sendBeacon
  if (navigator.sendBeacon) {
    navigator.sendBeacon('/api/metrics', JSON.stringify(data));
  } else {
    // 降级方案
    const img = new Image();
    img.src = `/api/metrics?data=${encodeURIComponent(JSON.stringify(data))}`;
  }
}

批量上报

class PerformanceCollector {
  constructor() {
    this.metrics = [];
    this.timer = null;
  }
  
  collect(name, value, tags) {
    this.metrics.push({ name, value, tags, timestamp: Date.now() });
    
    if (this.metrics.length >= 20) {
      this.report();
    } else {
      this.scheduleReport();
    }
  }
  
  scheduleReport() {
    if (this.timer) {
      clearTimeout(this.timer);
    }
    
    this.timer = setTimeout(() => {
      this.report();
    }, 10000); // 10秒后上报
  }
  
  report() {
    if (this.metrics.length === 0) return;
    
    const data = this.metrics.slice();
    this.metrics = [];
    
    fetch('/api/metrics', {
      method: 'POST',
      body: JSON.stringify(data),
    }).catch(err => {
      console.error('Report failed:', err);
      this.metrics.unshift(...data);
    });
  }
}

性能分析

1. 性能统计

统计维度:

  • 平均值
  • 中位数
  • P75、P95、P99
  • 最大值、最小值

2. 性能趋势

趋势分析:

  • 时间趋势
  • 版本对比
  • 用户分布

3. 性能优化建议

自动分析:

  • 慢资源识别
  • 性能瓶颈定位
  • 优化建议生成

监控平台

1. Google Analytics

集成:

// 发送自定义指标
gtag('event', 'timing_complete', {
  name: 'load',
  value: loadTime,
});

2. 自建监控

服务端接口:

app.post('/api/metrics', (req, res) => {
  const metrics = req.body;
  
  // 存储指标
  saveMetrics(metrics);
  
  // 分析性能
  analyzePerformance(metrics);
  
  res.json({ success: true });
});

最佳实践

1. 指标采集

  • 采集核心指标(Web Vitals)
  • 采集自定义指标
  • 采集资源加载时间
  • 采集接口响应时间

2. 上报策略

  • 批量上报
  • 采样上报(减少数据量)
  • 失败重试
  • 页面卸载时上报

3. 性能分析

  • 统计性能指标
  • 分析性能趋势
  • 定位性能瓶颈
  • 生成优化建议

4. 告警机制

  • 性能阈值告警
  • 异常波动告警
  • 自动通知
最近更新:: 2025/11/20 14:50
Contributors: liyulai
Prev
错误监控
Next
前端监控面试题