Fluxos de usuários do Lighthouse

Teste a nova API Lighthouse para avaliar o desempenho e as práticas recomendadas em todo o fluxo de usuários.

Brendan kenny
Brendan Kenny

O Lighthouse é uma ferramenta fantástica para testar o desempenho e as práticas recomendadas durante o carregamento inicial da página. No entanto, tradicionalmente é difícil usar o Lighthouse para analisar outros aspectos da vida de uma página, como:

  • A página é carregada com um cache quente
  • Páginas com um service worker ativado
  • Contabilização de possíveis interações do usuário

Isso significa que o Lighthouse pode não perceber informações vitais. As Core Web Vitals são baseadas em todos os carregamentos de página, não apenas naqueles com cache vazio. Além disso, métricas como a Mudança de layout cumulativa (CLS) são mensuráveis durante todo o tempo em que uma página está aberta.

O Lighthouse tem uma nova API de fluxo de usuários que permite testes de laboratório em qualquer ponto da vida útil de uma página. O Puppeteer é usado para criar scripts de carregamentos de página e acionar interações sintéticas do usuário. O Lighthouse pode ser invocado de várias maneiras para capturar insights importantes durante essas interações. Isso significa que o desempenho pode ser medido durante o carregamento da página e durante as interações com ela. As verificações de acessibilidade podem ser feitas na CI, não apenas na visualização inicial, mas profundamente no fluxo de finalização da compra para garantir que nada regresse.

Quase todos os scripts Puppeteer escritos para garantir um fluxo de usuários em funcionamento agora podem ter o Lighthouse inserido em qualquer ponto para medir o desempenho e as práticas recomendadas. Neste tutorial, mostraremos os novos modos do Lighthouse que podem medir diferentes partes dos fluxos de usuários: navegações, snapshots e períodos.

Instalação

As APIs de fluxo do usuário ainda estão em visualização, mas já estão disponíveis no Lighthouse. Para testar as demonstrações abaixo, você vai precisar do Node versão 14 ou mais recente. Crie um diretório vazio e execute nele:

# 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

O novo modo de "navegação" do Lighthouse está, na verdade, atribuindo um nome ao comportamento padrão (até agora) do Lighthouse: analisar o carregamento a frio de uma página. Esse é o modo usado para monitorar o desempenho de carregamento da página, mas os fluxos de usuários também abrem a possibilidade de novos insights.

Para criar um script do Lighthouse na captura de um carregamento de página:

  1. Use o puppeteer para abrir o navegador.
  2. Inicie um fluxo de usuários do Lighthouse.
  3. Navegue até o URL de destino.
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();

Este é o fluxo mais simples. Quando aberto, o relatório mostra uma visualização resumida com apenas uma etapa. Clique nessa etapa para exibir um relatório tradicional do Lighthouse para essa navegação.

Um relatório de fluxo do Lighthouse mostrando uma única navegação
Confira o relatório publicado

Como é comum no Lighthouse, essa página é carregada primeiro com qualquer cache ou armazenamento local limpo. No entanto, os usuários reais que visitarem um site terão uma mistura de visitas com caches frios e quentes, e pode haver uma grande diferença de desempenho entre uma carga a frio como essa e um usuário retornando à página com um cache ainda inativo.

Como capturar uma carga quente

Também é possível adicionar uma segunda navegação a esse script, dessa vez desativando a limpeza de cache e armazenamento que o Lighthouse faz por padrão nas navegações. O próximo exemplo carrega um artigo no próprio web.dev para ver os benefícios do armazenamento em cache:

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();

O Relatório de fluxo resultante é semelhante a este:

Um relatório de fluxo do Lighthouse mostrando duas navegações, uma frio e outra quente, que tem uma pontuação de performance mais alta
Confira o relatório publicado

A combinação de cargas frias e quentes oferece uma imagem mais completa da experiência dos usuários reais. Se você tiver um site em que os usuários carregam muitas páginas na mesma visita, isso poderá oferecer uma visão mais realista da experiência deles no campo.

Snapshots

Os snapshots são um novo modo que executa auditorias do Lighthouse em um único momento. Ao contrário de uma execução normal do Lighthouse, a página não é recarregada. Com isso, é possível configurar e testar uma página no estado exato em que ela aparece, por exemplo, com um menu suspenso aberto ou um formulário parcialmente preenchido.

Neste exemplo, suponha que você queira conferir se alguma nova IU para configurações avançadas no Squoosh passa pelas verificações automáticas do Lighthouse. Essas configurações só ficarão visíveis se uma imagem tiver sido carregada e o menu de opções for expandido para mostrar as configurações avançadas.

Menu de configurações avançadas do Squoosh
Menu de configurações avançadas do Squoosh

Esse processo pode ser executado em scripts com o Puppeteer, e é possível tirar um instantâneo do Lighthouse em cada etapa:

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();

O relatório resultante mostra que os resultados geralmente são bons, mas pode haver alguns critérios de acessibilidade que precisem ser verificados manualmente:

Um relatório de fluxo do Lighthouse mostrando um conjunto de snapshots capturados
Confira o relatório publicado

Períodos

Uma das maiores diferenças entre os resultados de desempenho no campo (como no CrUX) e no laboratório (como no Lighthouse) é a falta de entradas do usuário. É aqui que um período, o último modo de fluxo do usuário, pode ajudar.

Um período realiza auditorias do Lighthouse durante um período, que pode ou não incluir uma navegação. Essa é uma ótima maneira de capturar o que está acontecendo com uma página durante as interações. Por exemplo, por padrão, o Lighthouse mede a CLS durante o carregamento da página, mas, em campo, ela é medida a partir da navegação inicial até que a página seja fechada. Se as interações do usuário são o gatilho da CLS, isso é algo que antes o Lighthouse não conseguiria detectar e ajudar a corrigir.

Para demonstrar isso, veja um site de teste que simula a injeção de anúncios em um artigo durante a rolagem, sem reservar espaço para eles. Em uma longa série de cards, um quadrado vermelho é adicionado quando o slot entra na janela de visualização. Como o espaço não era reservado para esses quadrados vermelhos, os cartões abaixo deles são deslocados do caminho, causando mudanças de layout.

Uma navegação normal do Lighthouse terá um CLS de 0. No entanto, uma vez rolada, a página terá mudanças de layout problemáticas e o valor da CLS aumentará.

Acesse o site de demonstração

O script a seguir produzirá um relatório de fluxo do usuário com as duas ações para mostrar a diferença.

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();

Isso gera um relatório que compara uma navegação normal com um período que contém uma navegação e uma rolagem depois:

Um relatório de fluxo do Lighthouse mostrando um conjunto de snapshots capturados
Confira o relatório publicado

Analisando cada etapa, a etapa somente navegação mostra um CLS de 0. Ótimo site!

O relatório do Lighthouse abrange apenas a navegação nas páginas com todas as métricas em verde.

No entanto, a etapa "Navegar e rolar" conta uma história diferente. No momento, apenas o Tempo de bloqueio total e a Mudança de layout cumulativa estão disponíveis em períodos, mas o conteúdo de carregamento lento nessa página reduz claramente a CLS do site.

O relatório do Lighthouse sobre a navegação e a rolagem nas páginas com uma CLS com falha

Antes, o Lighthouse não conseguia identificar esse comportamento problemático de CLS, embora ele quase certamente apareceria na experiência de usuários reais. Os testes de desempenho com interações com script melhoram significativamente a fidelidade do laboratório.

Quero feedback

As novas APIs de fluxo de usuários no Lighthouse podem fazer muitas coisas novas, mas ainda pode ser complicado medir os tipos de cenários que seus usuários encontram.

Em caso de dúvidas, entre em contato nos fóruns de discussão do Lighthouse e registre bugs ou sugestões no Issue Tracker.