Synthetic Monitoring

Synthetic Monitoring — автоматизированное тестирование производительности приложения по расписанию из контролируемой среды (заданное устройство, сеть, браузер), позволяющее отслеживать тренды и обнаруживать регрессии без ожидания реальных пользователей.

Зачем нужно

RUM работает только при наличии трафика. Synthetic мониторинг проверяет производительность 24/7 в предсказуемых условиях: ночные деплои, изменения в CDN, деградация сторонних скриптов — обнаруживаются немедленно. Дополняет, но не заменяет RUM.

Где используется

  • Ежечасные Lighthouse проверки staging и production
  • Обнаружение регрессий после каждого деплоя
  • Сравнение производительности в разных регионах
  • Uptime monitoring с метриками производительности

Основной контент

Lighthouse CI — синтетический мониторинг в CI/CD

# .github/workflows/lighthouse.yml
name: Synthetic Performance Test

on:
  push:
    branches: [main]
  schedule:
    - cron: '0 * * * *'  # Каждый час

jobs:
  lighthouse:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Lighthouse Audit
        uses: treosh/lighthouse-ci-action@v12
        with:
          urls: |
            https://example.com/
            https://example.com/products
            https://example.com/checkout
          budgetPath: ./budget.json()
          uploadArtifacts: true

Playwright + web-vitals для synthetic мониторинга

// tests/performance.spec.js
import { test, expect } from '@playwright/test';

test('Core Web Vitals — homepage', async ({ page }) => {
  // Эмуляция медленного устройства
  await page.emulateMedia({ colorScheme: 'light' });
  await page.setViewportSize({ width: 390, height: 844 });

  // Throttle CPU и сеть
  const client = await page.context.newCDPSession(page);
  await client.send('Network.emulateNetworkConditions', {
    offline: false,
    downloadThroughput: (4 * 1024 * 1024) / 8, // 4Mbps
    uploadThroughput: (3 * 1024 * 1024) / 8,
    latency: 30,
  });
  await client.send('Emulation.setCPUThrottlingRate', { rate: 4 });

  const startTime = Date.now();
  await page.goto('https://example.com/', { waitUntil: 'networkidle' });

  // Измеряем метрики
  const metrics = await page.evaluate( => ({
    lcp: performance
      .getEntriesByType('largest-contentful-paint')
      .at(-1)?.startTime,
    cls: performance.getEntriesByType('layout-shift').reduce((sum, e) => sum + e.value, 0),
    ttfb: performance.getEntriesByType('navigation')[0]?.responseStart,
  }));

  expect(metrics.lcp).toBeLessThan(2500);
  expect(metrics.cls).toBeLessThan(0.1);
  expect(metrics.ttfb).toBeLessThan(800);
});

Grafana + Lighthouse scheduler

# Lighthouse CI server — хранение исторических данных
npx lhci server --storage.storageMethod=sql \
  --storage.sqlDatabasePath=./lhci.db

# Запуск из cron:
npx lhci collect --url=https://example.com
npx lhci upload --target=lhci \
  --serverBaseUrl=https://lhci.example.com \
  --token=$LHCI_TOKEN

# Экспорт метрик в Prometheus для Grafana:
# lighthouse-ci-server имеет /v1/projects/{id}/builds API

WebPageTest API — продвинутый synthetic тест

# API запрос к WebPageTest
curl "https://www.webpagetest.org/runtest.php" \
  -d "url=https://example.com" \
  -d "k=$WPT_API_KEY" \
  -d "f=json" \
  -d "location=Dulles:Chrome.Cable" \
  -d "runs=3" \
  -d "video=1"

Частые ошибки

  • Только synthetic без RUM — лабораторные результаты расходятся с реальностью
  • Тестирование только одного URL — регрессия на глубоких страницах не обнаруживается
  • Отсутствие CPU throttling — серверная машина намного быстрее телефона пользователя
  • Запуск теста только при деплое — ночные проблемы CDN/DNS не обнаруживаются

Связанные темы

Ресурсы