Настройка автоматического отчёта Lighthouse при каждом деплое
Lighthouse запускают вручную, когда что-то уже сломалось. Автоматический запуск при каждом деплое переворачивает логику: регрессии видны до того, как попали в прод, и есть точный коммит, который их вызвал.
Что нужно для полноценной автоматизации
Минимальный стек: CI/CD (GitHub Actions, GitLab CI, CircleCI) + Lighthouse CI CLI + место для хранения результатов. Опционально: LHCI сервер для истории и сравнения.
Установка и базовая настройка
npm install --save-dev @lhci/cli
Конфигурационный файл в корне проекта .lighthouserc.js:
module.exports = {
ci: {
collect: {
// URL для проверки — указываем ключевые страницы
url: [
'http://localhost:3000/',
'http://localhost:3000/about',
'http://localhost:3000/catalog',
'http://localhost:3000/product/test-product',
],
// Запускаем 3 раза, берём медиану — убирает флуктуации
numberOfRuns: 3,
startServerCommand: 'npm run start:ci',
startServerReadyPattern: 'ready on',
startServerReadyTimeout: 30000,
},
assert: {
assertions: {
'categories:performance': ['warn', { minScore: 0.8 }],
'categories:accessibility': ['error', { minScore: 0.9 }],
'categories:best-practices': ['warn', { minScore: 0.85 }],
'categories:seo': ['error', { minScore: 0.9 }],
'first-contentful-paint': ['warn', { maxNumericValue: 2000 }],
'largest-contentful-paint': ['error', { maxNumericValue: 2500 }],
'total-blocking-time': ['warn', { maxNumericValue: 300 }],
'cumulative-layout-shift': ['error', { maxNumericValue: 0.1 }],
'speed-index': ['warn', { maxNumericValue: 3400 }],
},
},
upload: {
target: 'temporary-public-storage',
// или свой LHCI сервер:
// target: 'lhci',
// serverBaseUrl: 'https://lhci.example.com',
// token: process.env.LHCI_TOKEN,
},
},
};
GitHub Actions workflow
name: Lighthouse CI
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
jobs:
lighthouse:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Run Lighthouse CI
run: |
npm install -g @lhci/[email protected]
lhci autorun
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
LHCI_TOKEN: ${{ secrets.LHCI_TOKEN }}
LHCI_GITHUB_APP_TOKEN нужен для того, чтобы LHCI оставлял статус-чеки на PR и ссылку на отчёт прямо в интерфейсе GitHub.
GitLab CI вариант
lighthouse:
image: cypress/browsers:node18.12.0-chrome107
stage: test
script:
- npm ci
- npm run build
- npm install -g @lhci/cli
- lhci autorun
variables:
LHCI_TOKEN: $LHCI_TOKEN
artifacts:
paths:
- .lighthouseci/
reports:
junit: .lighthouseci/manifest.json
expire_in: 30 days
only:
- merge_requests
- main
Self-hosted LHCI сервер
temporary-public-storage удобен для старта, но хранит данные только 7 дней и не позволяет сравнивать PR с baseline. Для командного использования поднимаем свой сервер:
# docker-compose.yml
services:
lhci-server:
image: patrickhulce/lhci-server:latest
ports:
- "9001:9001"
volumes:
- lhci-data:/data
environment:
LHCI_STORAGE__SQL_DIALECT: sqlite
LHCI_STORAGE__SQL_DATABASE_PATH: /data/lhci.db
LHCI_BASIC_AUTH__USERNAME: admin
LHCI_BASIC_AUTH__PASSWORD: ${LHCI_ADMIN_PASSWORD}
volumes:
lhci-data:
После запуска создаём проект и токен:
lhci wizard
# Следуем инструкциям, получаем BUILD_TOKEN
Уведомления о деградации в Slack
LHCI сам по себе не отправляет Slack-уведомления, но это легко добавить через шаг в CI:
- name: Check Lighthouse results and notify
if: always()
run: |
RESULT=$(cat .lighthouseci/manifest.json | jq -r '.[0].summary.performance')
SCORE=$(echo "$RESULT * 100" | bc | cut -d. -f1)
if [ "$SCORE" -lt "80" ]; then
curl -X POST ${{ secrets.SLACK_WEBHOOK }} \
-H 'Content-Type: application/json' \
-d "{
\"text\": \":warning: Lighthouse Performance score dropped to ${SCORE}/100 on \`${{ github.ref_name }}\`\",
\"attachments\": [{
\"color\": \"danger\",
\"text\": \"Commit: ${{ github.sha }}\nActor: ${{ github.actor }}\"
}]
}"
fi
Проверка конкретных аудитов
Помимо категорийных скоров, можно проверять конкретные аудиты. Это полезнее — скор 80 может быть достигнут при плохих метриках, если остальное отличное.
// .lighthouserc.js
assert: {
assertions: {
// Запрещаем render-blocking ресурсы
'render-blocking-resources': 'error',
// Изображения должны иметь явные размеры
'unsized-images': 'error',
// Предупреждаем об использовании document.write
'no-document-write': 'warn',
// Используется ли современный формат изображений
'uses-webp-images': 'warn',
// LCP изображение должно иметь preload
'prioritize-lcp-image': 'warn',
},
},
Параллельный запуск для нескольких страниц
При большом числе URL запуск по одному занимает много времени. Параллелизуем:
strategy:
matrix:
url:
- http://localhost:3000/
- http://localhost:3000/catalog
- http://localhost:3000/product/example
steps:
- name: Run Lighthouse for ${{ matrix.url }}
run: lhci collect --url="${{ matrix.url }}" --numberOfRuns=3
Сроки
Базовая настройка LHCI в GitHub Actions с temporary-public-storage — 2–4 часа. Self-hosted LHCI сервер + Slack-уведомления + настройка порогов для ключевых страниц — 1–2 рабочих дня. Полноценная система с параллельным запуском, историей, сравнением с baseline и интеграцией в ревью-процесс — 3–5 рабочих дней.







