Потоки пользователей Lighthouse

Попробуйте новый API Lighthouse для измерения производительности и лучших практик на протяжении всего пользовательского потока.

Брендан Кенни
Brendan Kenny

Lighthouse — фантастический инструмент для тестирования производительности и лучших практик во время начальной загрузки страницы. Однако традиционно было сложно использовать Lighthouse для анализа других аспектов жизни страницы, таких как:

  • Страница загружается с теплым кешем
  • Страницы с активированным Service Worker
  • Учет потенциального взаимодействия с пользователем

Это означает, что Маяк может пропустить важную информацию. Основные веб-показатели основаны на всех загрузках страниц, а не только на тех, у которых кеш пуст. Кроме того, такие показатели, как совокупный сдвиг макета (CLS), можно измерить за все время открытия страницы.

У Lighthouse есть новый API пользовательского потока, который позволяет проводить лабораторные испытания в любой момент жизненного цикла страницы. Puppeteer используется для создания скриптов загрузки страниц и запуска синтетических взаимодействий с пользователем, а Lighthouse можно вызывать несколькими способами для получения ключевой информации во время этих взаимодействий. Это означает, что производительность можно измерить во время загрузки страницы и во время взаимодействия с ней. Проверки доступности можно запускать в CI не только при первоначальном представлении, но и глубоко в процессе оформления заказа, чтобы убедиться, что ничего не ухудшилось.

Почти в любой скрипт Puppeteer, написанный для обеспечения рабочего потока пользователей, теперь в любой момент можно вставить Lighthouse для измерения производительности и лучших практик. В этом руководстве будут рассмотрены новые режимы Lighthouse, которые могут измерять различные части пользовательских потоков: навигацию, снимки и временные интервалы.

Настраивать

API-интерфейсы пользовательского потока все еще находятся в предварительной версии, но они доступны в Lighthouse уже сегодня. Чтобы опробовать приведенные ниже демонстрации, вам понадобится Node версии 14 или новее. Создайте пустой каталог и запустите в нем:

# Default to ES modules.
echo '{"type": "module"}' > package.json

# Init npm project without the wizard.
npm init -y

# Dependencies for these examples.
npm install lighthouse puppeteer open

Новый режим «навигации» Lighthouse фактически дает название (до сих пор) стандартному поведению Lighthouse: анализировать холодную загрузку страницы. Этот режим можно использовать для мониторинга производительности загрузки страниц, но потоки пользователей также открывают возможность получения новой информации.

Чтобы создать сценарий Lighthouse, фиксирующий загрузку страницы:

  1. Используйте puppeteer, чтобы открыть браузер.
  2. Запустите пользовательский поток Lighthouse.
  3. Перейдите к целевому URL-адресу.
import fs from 'fs';
import open from 'open';
import puppeteer from 'puppeteer';
import {startFlow} from 'lighthouse/lighthouse-core/fraggle-rock/api.js';

async function captureReport() {
  const browser = await puppeteer.launch({headless: false});
  const page = await browser.newPage();

  const flow = await startFlow(page, {name: 'Single Navigation'});
  await flow.navigate('https://web.dev/performance-scoring/');

  await browser.close();

  const report = await flow.generateReport();
  fs.writeFileSync('flow.report.html', report);
  open('flow.report.html', {wait: false});
}

captureReport();

Это самый простой поток. При открытии отчет показывает сводное представление только с одним шагом. Нажав на этот шаг, вы увидите традиционный отчет Lighthouse для этой навигации.

Отчет о потоке Lighthouse, показывающий одну навигацию
Смотрите отчет в прямом эфире

Как это типично для Lighthouse, эта страница загружается с предварительно очищенным кешем или локальным хранилищем, но реальные пользователи, посещающие сайт, будут иметь смесь посещений с холодным и теплым кешем, и между холодной загрузкой может быть большая разница в производительности, например это и пользователь, возвращающийся на страницу с еще теплым кешем.

Захват теплой нагрузки

Вы также можете добавить в этот скрипт вторую навигацию, на этот раз отключив очистку кеша и хранилища, которую Lighthouse выполняет по умолчанию в навигации. В следующем примере загружается статья на самом веб-сайте web.dev, чтобы увидеть, какую пользу он получает от кэширования:

async function captureReport() {
  const browser = await puppeteer.launch({headless: false});
  const page = await browser.newPage();

  const testUrl = 'https://web.dev/performance-scoring/';
  const flow = await startFlow(page, {name: 'Cold and warm navigations'});
  await flow.navigate(testUrl, {
    stepName: 'Cold navigation'
  });
  await flow.navigate(testUrl, {
    stepName: 'Warm navigation',
    configContext: {
      settingsOverrides: {disableStorageReset: true},
    },
  });

  await browser.close();

  const report = await flow.generateReport();
  fs.writeFileSync('flow.report.html', report);
  open('flow.report.html', {wait: false});
}

captureReport();

Итоговый отчет о потоке выглядит примерно так:

Отчет о потоке Lighthouse, показывающий две навигации: холодную и теплую, которые имеют более высокий показатель производительности.
Смотрите отчет в прямом эфире

Сочетание холодных и теплых нагрузок дает более полную картину того, что испытывают реальные пользователи. Если у вас есть сайт, на котором пользователи загружают много страниц за одно посещение, это может дать вам более реалистичное представление о том, с чем они сталкиваются в этой области.

Снимки

Снимки — это новый режим, в котором аудит Lighthouse выполняется в один момент времени. В отличие от обычного запуска Lighthouse, страница не перезагружается. Это открывает возможность настроить страницу и протестировать ее в точном состоянии: например, с открытым раскрывающимся списком или с частично заполненной формой.

В этом примере предположим, что вы хотите проверить, что какой-то новый пользовательский интерфейс для расширенных настроек в Squoosh проходит автоматические проверки Lighthouse. Эти настройки видны только в том случае, если изображение загружено и меню параметров развернуто, чтобы отобразить дополнительные настройки.

Меню дополнительных настроек Squoosh
Меню дополнительных настроек Squoosh

Этот процесс можно запрограммировать с помощью Puppeteer, и вы можете делать снимки Lighthouse на каждом этапе:

async function captureReport() {
  const browser = await puppeteer.launch({headless: false});
  const page = await browser.newPage();

  const flow = await startFlow(page, {name: 'Squoosh snapshots'});

  await page.goto('https://squoosh.app/', {waitUntil: 'networkidle0'});

  // Wait for first demo-image button, then open it.
  const demoImageSelector = 'ul[class*="demos"] button';
  await page.waitForSelector(demoImageSelector);
  await flow.snapshot({stepName: 'Page loaded'});
  await page.click(demoImageSelector);

  // Wait for advanced settings button in UI, then open them.
  const advancedSettingsSelector = 'form label[class*="option-reveal"]';
  await page.waitForSelector(advancedSettingsSelector);
  await flow.snapshot({stepName: 'Demo loaded'});
  await page.click(advancedSettingsSelector);

  await flow.snapshot({stepName: 'Advanced settings opened'});

  browser.close();

  const report = await flow.generateReport();
  fs.writeFileSync('flow.report.html', report);
  open('flow.report.html', {wait: false});
}

captureReport();

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

Отчет о потоке данных Lighthouse, показывающий набор сделанных снимков.
Смотрите отчет в прямом эфире

Промежутки времени

Одно из самых больших различий между результатами производительности в полевых условиях (например, от CrUX) и в лаборатории (например, от Lighthouse) — отсутствие участия пользователя. Здесь может помочь временной интервал — последний режим пользовательского потока.

Временной интервал запускает аудит Lighthouse в течение определенного периода времени, который может включать или не включать навигацию. Это отличный способ зафиксировать, что происходит со страницей во время взаимодействия. Например, по умолчанию Lighthouse измеряет CLS во время загрузки страницы, но в полевых условиях CLS измеряется с момента первоначальной навигации до закрытия страницы. Если взаимодействие с пользователем является триггером CLS, то Lighthouse раньше не мог это уловить и исправить.

Чтобы продемонстрировать это, вот тестовый сайт , который имитирует рекламу, вставляемую в статью во время прокрутки, без резервирования для нее места. В длинных сериях карт время от времени добавляется красный квадрат, когда его слот попадает в область просмотра. Поскольку для этих красных квадратов не было зарезервировано место, карты под ними смещаются, что приводит к смещению раскладки.

Обычная навигация Lighthouse будет иметь CLS, равный 0. Однако после прокрутки страница будет иметь проблемные сдвиги макета, и значение CLS увеличится.

Попробуйте демо-сайт

Следующий скрипт создаст отчет о потоке пользователя с обоими действиями, чтобы показать разницу.

async function captureReport() {
  const browser = await puppeteer.launch({headless: false});
  const page = await browser.newPage();
  // Get a session handle to be able to send protocol commands to the page.
  const session = await page.target().createCDPSession();

  const testUrl = 'https://pie-charmed-treatment.glitch.me/';
  const flow = await startFlow(page, {name: 'CLS during navigation and on scroll'});

  // Regular Lighthouse navigation.
  await flow.navigate(testUrl, {stepName: 'Navigate only'});

  // Navigate and scroll timespan.
  await flow.startTimespan({stepName: 'Navigate and scroll'});
  await page.goto(testUrl, {waitUntil: 'networkidle0'});
  // We need the ability to scroll like a user. There's not a direct puppeteer function for this, but we can use the DevTools Protocol and issue a Input.synthesizeScrollGesture event, which has convenient parameters like repetitions and delay to somewhat simulate a more natural scrolling gesture.
  // https://chromedevtools.github.io/devtools-protocol/tot/Input/#method-synthesizeScrollGesture
  await session.send('Input.synthesizeScrollGesture', {
    x: 100,
    y: 600,
    yDistance: -2500,
    speed: 1000,
    repeatCount: 2,
    repeatDelayMs: 250,
  });
  await flow.endTimespan();

  await browser.close();

  const report = await flow.generateReport();
  fs.writeFileSync('flow.report.html', report);
  open('flow.report.html', {wait: false});
}

captureReport();

При этом создается отчет, сравнивающий обычную навигацию с временным интервалом, который содержит как навигацию, так и последующую прокрутку:

Отчет о потоке данных Lighthouse, показывающий набор сделанных снимков.
Смотрите отчет в прямом эфире

Если углубляться в каждый шаг, то на этапе, предназначенном только для навигации, CLS равен 0. Отличный сайт!

Отчет Lighthouse, охватывающий только навигацию по страницам со всеми зелеными метриками.

Однако шаг «Навигация и прокрутка» говорит о другом. В настоящее время во временных интервалах доступны только общее время блокировки и совокупный сдвиг макета, но лениво загружаемый контент на этой странице явно снижает CLS для сайта.

Отчет Lighthouse, посвященный навигации по страницам и прокрутке с помощью неисправного CLS.

Раньше Lighthouse не мог выявить такое проблемное поведение CLS, хотя оно почти наверняка проявится в опыте реальных пользователей. Тестирование производительности с помощью скриптовых взаимодействий значительно повышает точность лабораторных исследований.

Ищем отзывы

Новые API-интерфейсы пользовательского потока в Lighthouse могут делать много новых вещей, но измерить сценарии, с которыми сталкиваются ваши пользователи, по-прежнему может быть сложно.

Пожалуйста, задавайте любые вопросы на дискуссионных форумах Lighthouse и сообщайте обо всех ошибках или предложениях в систему отслеживания проблем .