Skip to content

Chrome DevTools MCP 性能分析

本指南介绍如何使用 Chrome DevTools MCP 来分析和优化 Web 应用性能。

概述

Chrome DevTools MCP 提供了对浏览器性能分析工具的编程访问,让 AI 助手能够:

  • 自动化性能测试
  • 分析页面加载性能
  • 识别性能瓶颈
  • 生成优化建议

配置

1. 安装 Chrome DevTools MCP

bash
npm install -g chrome-devtools-mcp-server

2. 配置 ByteBuddy

json
{
  "mcpServers": {
    "chrome-devtools": {
      "command": "node",
      "args": ["chrome-devtools-mcp-server"],
      "env": {
        "CHROME_REMOTE_DEBUGGING_PORT": "9222",
        "TARGET_URL": "http://localhost:3000"
      }
    }
  }
}

3. 启动 Chrome 远程调试

bash
# 启动 Chrome 并开启远程调试
google-chrome --remote-debugging-port=9222 --disable-web-security

# 或者使用 headless 模式
google-chrome --headless --remote-debugging-port=9222

使用场景

场景 1: 性能审计

typescript
// 执行性能审计
const audit = await mcp.call("chrome.runLighthouse", {
  url: "http://localhost:3000",
  categories: ["performance", "accessibility", "best-practices"],
  settings: {
    throttling: {
      rttMs: 100,
      throughputKbps: 10000,
      cpuSlowdownMultiplier: 2,
    },
  },
});

console.log(
  `Performance Score: ${audit.lhr.categories.performance.score * 100}`,
);

场景 2: 网络分析

typescript
// 分析网络请求
const networkLogs = await mcp.call("chrome.getNetworkLogs", {
  timeRange: {
    start: Date.now() - 60000,
    end: Date.now(),
  },
});

// 识别慢速请求
const slowRequests = networkLogs.filter((request) => request.duration > 1000);

console.log("Slow requests:", slowRequests);

场景 3: 内存分析

typescript
// 检查内存泄漏
const memorySnapshot = await mcp.call("chrome.takeHeapSnapshot", {
  includeNodeId: true,
  includeRetainedPaths: true,
});

// 分析内存使用
const memoryAnalysis = await mcp.call("chrome.analyzeMemory", {
  snapshot: memorySnapshot,
  focusOnLeakedObjects: true,
});

性能优化策略

1. 自动化性能监控

typescript
class PerformanceMonitor {
  async auditPage(url: string) {
    const audit = await mcp.call("chrome.runLighthouse", { url });

    return {
      performance: audit.lhr.categories.performance.score,
      firstContentfulPaint:
        audit.lhr.audits["first-contentful-paint"].numericValue,
      largestContentfulPaint:
        audit.lhr.audits["largest-contentful-paint"].numericValue,
      cumulativeLayoutShift:
        audit.lhr.audits["cumulative-layout-shift"].numericValue,
    };
  }

  async generateReport(baseUrl: string, paths: string[]) {
    const results = [];

    for (const path of paths) {
      const url = `${baseUrl}${path}`;
      const metrics = await this.auditPage(url);
      results.push({ url, ...metrics });
    }

    return this.generateOptimizationSuggestions(results);
  }
}

2. 持续性能监控

yaml
# .github/workflows/performance.yml
name: Performance Audit
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  performance-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: "18"

      - name: Install dependencies
        run: npm ci

      - name: Build application
        run: npm run build

      - name: Start application
        run: npm run start &

      - name: Wait for app to be ready
        run: sleep 30

      - name: Run performance audit
        run: |
          bytebuddy --mcp chrome-devtools --audit-performance \
            --url http://localhost:3000 \
            --output performance-report.json

      - name: Check performance threshold
        run: |
          node scripts/check-performance-threshold.js

3. 性能回归检测

typescript
// 性能阈值检查
const performanceThresholds = {
  performanceScore: 0.9,
  firstContentfulPaint: 1500,
  largestContentfulPaint: 2500,
  cumulativeLayoutShift: 0.1,
};

async function checkPerformanceRegression() {
  const currentMetrics = await getCurrentPerformanceMetrics();
  const baselineMetrics = await getBaselineMetrics();

  const regressions = [];

  for (const [metric, threshold] of Object.entries(performanceThresholds)) {
    const currentValue = currentMetrics[metric];
    const baselineValue = baselineMetrics[metric];

    if (currentValue < baselineValue * 0.95) {
      regressions.push({
        metric,
        current: currentValue,
        baseline: baselineValue,
        regression: baselineValue - currentValue,
      });
    }
  }

  return regressions;
}

高级分析

1. 自定义性能指标

typescript
// 定义自定义指标
const customMetrics = {
  timeToInteractive: {
    measurement: () => {
      return new Promise((resolve) => {
        const observer = new PerformanceObserver((list) => {
          const entries = list.getEntries();
          const tti = entries.find(
            (entry) => entry.name === "time-to-interactive",
          );
          if (tti) {
            resolve(tti.startTime);
          }
        });
        observer.observe({ entryTypes: ["measure"] });
      });
    },
  },

  renderBlockingTime: {
    measurement: async () => {
      const navigation = performance.getEntriesByType("navigation")[0];
      const domContentLoaded = navigation.domContentLoadedEventStart;
      const firstPaint = performance.getEntriesByType("paint")[0].startTime;
      return domContentLoaded - firstPaint;
    },
  },
};

2. Core Web Vitals 监控

typescript
// Core Web Vitals 监控
class CoreWebVitalsMonitor {
  constructor() {
    this.metrics = {};
  }

  startMonitoring() {
    // LCP
    new PerformanceObserver((list) => {
      const entries = list.getEntries();
      const lastEntry = entries[entries.length - 1];
      this.metrics.largestContentfulPaint = lastEntry.startTime;
    }).observe({ entryTypes: ["largest-contentful-paint"] });

    // CLS
    let clsValue = 0;
    new PerformanceObserver((list) => {
      for (const entry of list.getEntries()) {
        if (!entry.hadRecentInput) {
          clsValue += entry.value;
        }
      }
      this.metrics.cumulativeLayoutShift = clsValue;
    }).observe({ entryTypes: ["layout-shift"] });

    // FID (需要用户交互)
    new PerformanceObserver((list) => {
      for (const entry of list.getEntries()) {
        this.metrics.firstInputDelay = entry.processingStart - entry.startTime;
      }
    }).observe({ entryTypes: ["first-input"] });
  }

  getMetrics() {
    return this.metrics;
  }
}

优化建议生成

typescript
// 自动生成优化建议
class PerformanceOptimizer {
  generateOptimizationSuggestions(auditResults) {
    const suggestions = [];

    // 基于性能分数的建议
    if (auditResults.performance < 0.9) {
      suggestions.push({
        category: "Performance",
        issue: "Performance score is below 90%",
        suggestions: ["优化图片资源", "减少 JavaScript 包大小", "启用资源压缩"],
      });
    }

    // 基于具体指标的建议
    if (auditResults.firstContentfulPaint > 1500) {
      suggestions.push({
        category: "First Contentful Paint",
        issue: `FCP is ${auditResults.firstContentfulPaint}ms (threshold: 1500ms)`,
        suggestions: ["内联关键 CSS", "预加载关键资源", "优化服务器响应时间"],
      });
    }

    // 基于网络请求的建议
    if (auditResults.slowRequests.length > 0) {
      suggestions.push({
        category: "Network",
        issue: `${auditResults.slowRequests.length} slow requests detected`,
        suggestions: ["实现请求缓存", "使用 CDN", "优化 API 响应时间"],
      });
    }

    return suggestions;
  }
}

故障排除

常见问题

Chrome 远程调试无法连接

bash
# 检查端口是否开放
netstat -tlnp | grep 9222

# 重新启动 Chrome
pkill chrome
google-chrome --remote-debugging-port=9222

性能审计失败

typescript
// 添加重试机制
async function runAuditWithRetry(url, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await mcp.call("chrome.runLighthouse", { url });
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await new Promise((resolve) => setTimeout(resolve, 2000));
    }
  }
}

内存快照过大

json
{
  "chrome-devtools": {
    "env": {
      "HEAP_SNAPSHOT_COMPRESSION": "gzip",
      "MAX_SNAPSHOT_SIZE": "50MB"
    }
  }
}

通过 Chrome DevTools MCP,ByteBuddy 可以提供深入的性能分析和优化建议,帮助开发者构建更快的 Web 应用。