Кастомные gatherers

Gatherers в Lighthouse представляют собой модули, отвечающие за сбор данных о веб-странице. По умолчанию Lighthouse предоставляет набор стандартных gatherers, таких как ViewportDimensions, CriticalRequestChains или CSSUsage. Однако часто требуется получить специфическую информацию, недоступную через стандартные gatherers. Для этого используются кастомные gatherers — пользовательские скрипты, расширяющие возможности анализа.


Основная структура кастомного gatherer

Кастомный gatherer в Lighthouse реализуется как класс с методом afterPass или beforePass. Методы имеют доступ к контексту страницы через объект artifacts и позволяют выполнять любые операции с DOM или сетевыми данными.

Пример минимальной структуры:

const Gatherer = require('lighthouse/lighthouse-core/gather/gatherers/gatherer.js');

class CustomGatherer extends Gatherer {
  constructor() {
    super();
    this.meta = {
      name: 'custom-gatherer',
      description: 'Собирает информацию о всех изображениях на странице',
      supportedModes: ['navigation']
    };
  }

  async afterPass(options) {
    const driver = options.driver;

    const images = await driver.evaluate(() => {
      return Array.from(document.images).map(img => ({
        src: img.src,
        width: img.width,
        height: img.height
      }));
    });

    return images;
  }
}

module.exports = CustomGatherer;

Разбор ключевых элементов:

  • extends Gatherer — наследование от базового класса gatherer, что обеспечивает совместимость с Lighthouse.
  • meta — объект с метаданными: имя gatherer, описание и режимы запуска (navigation или timespan).
  • afterPass — основной метод для сбора данных. Вызывается после полной загрузки страницы, что гарантирует корректность собранной информации.
  • driver.evaluate — выполняет код в контексте страницы, позволяя собирать данные из DOM.

Методы beforePass и afterPass

beforePass запускается до начала загрузки страницы. Используется для установки наблюдателей или перехвата сетевых запросов:

async beforePass(options) {
  const driver = options.driver;

  await driver.sendCommand('Network.enable');
  await driver.sendCommand('Network.setRequestInterception', {
    patterns: [{ urlPattern: '*' }]
  });

  driver.on('Network.requestIntercepted', event => {
    console.log('Перехваченный запрос:', event.request.url);
  });
}

afterPass вызывается после загрузки страницы и позволяет анализировать DOM, собирать метрики или фильтровать ресурсы. Для большинства кастомных gatherers используется именно этот метод, так как данные страницы уже загружены полностью.


Работа с артефактами (artifacts)

Artifacts — это объект, передаваемый в gatherer, содержащий информацию о странице, доступную для анализа. Стандартные gatherers возвращают артефакты, которые затем используются аудитами. Кастомные gatherers также должны возвращать объект или массив, который станет новым артефактом.

Пример создания артефакта с данными о всех ссылках на странице:

async afterPass(options) {
  const driver = options.driver;

  const links = await driver.evaluate(() => {
    return Array.from(document.querySelectorAll('a')).map(a => ({
      href: a.href,
      text: a.textContent.trim()
    }));
  });

  return links; // это станет артефактом для аудитов
}

Подключение кастомного gatherer в конфигурацию Lighthouse

Кастомный gatherer добавляется в конфигурацию Lighthouse через объект gatherers:

const config = {
  passes: [
    {
      passName: 'defaultPass',
      gatherers: [
        './gatherers/custom-gatherer.js',
        'viewport-dimensions'
      ]
    }
  ],
  audits: ['performance-budget', 'uses-rel-preconnect'],
  categories: {
    performance: {
      title: 'Performance',
      auditRefs: [
        { id: 'performance-budget', weight: 1 }
      ]
    }
  }
};

module.exports = config;

Важно: путь к кастомному gatherer должен быть относительным к файлу конфигурации.


Советы по разработке кастомных gatherers

  • Использовать driver.evaluate для доступа к DOM, а driver.sendCommand для работы с сетевыми или браузерными командами.
  • Обрабатывать ошибки внутри gatherer, чтобы не нарушать выполнение Lighthouse.
  • Минимизировать нагрузку на страницу: не блокировать рендер и не производить тяжелые операции на клиенте.
  • Проверять совместимость с режимами navigation и timespan, особенно если gatherer требует нескольких проходов страницы.

Пример сложного gatherer с фильтрацией ресурсов

class ResourceGatherer extends Gatherer {
  constructor() {
    super();
    this.meta = {
      name: 'resource-gatherer',
      description: 'Собирает только изображения и скрипты на странице',
      supportedModes: ['navigation']
    };
  }

  async afterPass(options) {
    const driver = options.driver;
    const networkRecords = await driver.getRequestContent({includeData: true});

    return networkRecords
      .filter(record => record.resourceType === 'Image' || record.resourceType === 'Script')
      .map(record => ({
        url: record.url,
        size: record.transferSize
      }));
  }
}

module.exports = ResourceGatherer;

Этот gatherer позволяет не только получить данные о ресурсах страницы, но и фильтровать их по типу, создавая полезный артефакт для последующего анализа аудитов.


Кастомные gatherers обеспечивают гибкость Lighthouse и позволяют интегрировать специфические проверки производительности, безопасности или SEO. Их разработка требует аккуратного обращения с DOM и сетевыми данными, строгого соблюдения структуры классов и возвращаемых артефактов.