Система сбора данных в Lighthouse построена вокруг концепции gatherers (сборщиков), которые извлекают информацию из браузера во время выполнения аудита. Каждый gatherer отвечает за получение строго определённого типа данных, формируя на выходе артефакты — структурированные результаты, используемые аудитами.
В основе лежит разделение ответственности:
Такое разделение обеспечивает масштабируемость и повторное использование логики.
Каждый gatherer проходит три ключевых этапа:
Вызывается перед загрузкой страницы. Используется для настройки окружения:
async beforePass({driver}) {
await driver.sendCommand('Network.enable');
}
Выполняется во время загрузки страницы:
async pass({driver}) {
this.requests = [];
driver.on('Network.requestWillBeSent', req => {
this.requests.push(req);
});
}
Запускается после полной загрузки страницы:
async afterPass() {
return this.requests;
}
Gatherers работают в двух средах:
const result = await driver.evaluateAsync(`
new Promise(resolve => {
resolve(document.title);
});
`);
Ключевой компонент — driver, абстракция над CDP. Позволяет:
await driver.sendCommand('Page.enable');
Примеры возможностей:
Network.* — отслеживание запросовPerformance.* — метрики производительностиDOM.* — работа с DOMАртефакт — это результат работы gatherer, представленный в виде JSON-совместимой структуры.
Пример:
{
"URL": "https://example.com",
"Timing": {
"firstContentfulPaint": 1234
}
}
Артефакты сохраняются и передаются аудитам без изменений.
Пример сложного артефакта:
{
resources: [
{url: 'style.css', type: 'stylesheet'},
{url: 'app.js', type: 'script'}
],
totalSize: 34567
}
Каждый gatherer объявляет имя артефакта, который он возвращает.
class MyGatherer {
get name() {
return 'MyArtifact';
}
}
Это имя используется:
Аудиты получают доступ к артефактам через объект
artifacts:
static audit(artifacts) {
const data = artifacts.MyArtifact;
return {
score: data.length > 0 ? 1 : 0
};
}
Артефакты не модифицируются аудитами — только читаются.
Gatherers активно используют async/await:
Важно:
Lighthouse автоматически кэширует артефакты:
Это снижает:
const Gatherer = require('lighthouse').Gatherer;
class MetaDescriptionGatherer extends Gatherer {
async afterPass({driver}) {
const description = await driver.evaluateAsync(`
new Promise(resolve => {
const el = document.querySelector('meta[name="description"]');
resolve(el ? el.content : null);
});
`);
return description;
}
}
module.exports = MetaDescriptionGatherer;
В конфигурации Lighthouse:
module.exports = {
passes: [
{
passName: 'defaultPass',
gatherers: [
'./gatherers/meta-description.js'
]
}
]
};
Gatherers должны быть устойчивыми к сбоям:
Рекомендуется:
try {
return await driver.evaluateAsync(...);
} catch (e) {
return null;
}
Не рекомендуется:
Рекомендуется:
Gatherers группируются в passes — этапы выполнения аудита.
Каждый pass:
Добавление нового gatherer:
Инструменты:
lighthouse-loggerconst log = require('lighthouse-logger');
log.info('Category', 'Message');
Некоторые gatherers используют trace:
Trace собирается отдельно и передаётся как артефакт:
artifacts.traces.defaultPass
DevTools Log (devtoolsLog) — ещё один важный артефакт:
artifacts.devtoolsLogs.defaultPass
Ключевое требование:
Для этого:
Gatherers формируют фундамент всей системы:
Именно через них Lighthouse превращает поведение браузера в структурированную, анализируемую информацию.