Flussi utente di Lighthouse

Prova una nuova API Lighthouse per misurare le prestazioni e le best practice in un flusso utente.

Brendan Kenny
Brendan Kenny

Lighthouse è uno strumento fantastico per testare le prestazioni e le best practice durante il caricamento pagina iniziale. Tuttavia, tradizionalmente è stato difficile utilizzare Lighthouse per analizzare altri aspetti della vita di una pagina, ad esempio:

  • Caricamenti pagina con una cache warm
  • Pagine con un service worker attivato
  • Considerare le potenziali interazioni degli utenti

Ciò significa che Lighthouse potrebbe non rilevare informazioni vitali. I Core Web Vitals si basano su tutti i caricamenti pagina, non solo su quelli con una cache vuota. Inoltre, metriche come Cumulative Layout Shift (CLS) sono misurabili per tutto il tempo in cui una pagina è aperta.

Lighthouse ha una nuova API per il flusso utente che consente di eseguire test di laboratorio in qualsiasi momento del ciclo di vita di una pagina. Puppeteer viene utilizzato per creare script per i caricamenti pagina e attivare interazioni utente sintetiche, mentre Lighthouse può essere richiamato in diversi modi per acquisire informazioni chiave durante queste interazioni. Ciò significa che il rendimento può essere misurato durante il caricamento pagina e durante le interazioni con la pagina. I controlli di accessibilità possono essere eseguiti in CI, non solo nella visualizzazione iniziale, ma anche in profondità nel flusso di checkout per assicurarsi che non ci siano regressioni.

Quasi tutti gli script Puppeteer scritti per garantire un flusso utente funzionante ora possono avere Lighthouse inserito in qualsiasi punto per misurare le prestazioni e le best practice. Questo tutorial illustra le nuove modalità di Lighthouse che possono misurare diverse parti dei flussi utente: navigazioni, istantanee e periodi di tempo.

Configurazione

Le API per i flussi utente sono ancora in anteprima, ma sono già disponibili in Lighthouse. Per provare le demo di seguito, devi avere Node versione 14 o successive. Crea una directory vuota ed esegui al suo interno:

# 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

La nuova modalità "Navigazione" di Lighthouse dà un nome al comportamento standard di Lighthouse (fino ad ora): analizzare il caricamento completo di una pagina. Questa è la modalità da utilizzare per monitorare le prestazioni di caricamento pagina, ma i flussi utente aprono anche la possibilità di nuovi approfondimenti.

Per creare uno script di Lighthouse che acquisisca un caricamento pagina:

  1. Utilizza Puppeteer per aprire il browser.
  2. Avvia un flusso utente di Lighthouse.
  3. Vai all'URL di destinazione.
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();

Questo è il flusso più semplice. All'apertura, il report mostra una visualizzazione di riepilogo con un solo passaggio. Se fai clic su questo passaggio, viene visualizzato un report Lighthouse tradizionale per la navigazione.

Un report sui flussi di Lighthouse che mostra una singola navigazione

Come di consueto con Lighthouse, questa pagina viene caricata dopo aver svuotato la cache o lo spazio di archiviazione locale, ma gli utenti reali che visitano un sito avranno un mix di visite con cache fredde e calde e può esserci una grande differenza di prestazioni tra un caricamento completo come questo e un utente che torna alla pagina con una cache ancora calda.

Acquisizione di un carico caldo

Puoi anche aggiungere una seconda navigazione a questo script, questa volta disattivando la cancellazione della cache e dello spazio di archiviazione che Lighthouse esegue per impostazione predefinita nelle navigazioni. L'esempio seguente carica un articolo su web.dev per vedere quanto beneficia della memorizzazione nella 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();

Il report sul flusso risultante ha il seguente aspetto:

Un report sui flussi di Lighthouse che mostra due navigazioni, una a freddo e una a caldo, con un punteggio di rendimento più elevato

La combinazione di caricamenti a freddo e a caldo offre un quadro più completo di ciò che sperimentano gli utenti reali. Se hai un sito in cui gli utenti caricano molte pagine nella stessa visita, questo potrebbe darti un'idea più realistica di ciò che stanno riscontrando sul campo.

Snapshot

Gli snapshot sono una nuova modalità che esegue i controlli di Lighthouse in un singolo momento. A differenza di una normale esecuzione di Lighthouse, la pagina non viene ricaricata. In questo modo, puoi configurare una pagina e testarla nel suo stato esatto, ad esempio con un menu a discesa aperto o un modulo parzialmente compilato.

Per questo esempio, supponiamo che tu voglia verificare che una nuova UI per le Impostazioni avanzate di Squoosh superi i controlli automatici di Lighthouse. Queste impostazioni sono visibili solo se è stata caricata un'immagine e il menu opzioni è stato espanso per mostrare le impostazioni avanzate.

Il menu delle impostazioni avanzate di Squoosh
Il menu delle impostazioni avanzate di Squoosh

Questo processo è programmabile con Puppeteer e puoi effettivamente acquisire un'istantanea di Lighthouse in ogni passaggio:

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

Il report risultante mostra che i risultati sono generalmente buoni, ma potrebbero esserci alcuni criteri di accessibilità che devono essere controllati manualmente:

Un report sul flusso di Lighthouse che mostra un insieme di istantanee acquisite

Periodi di tempo

Una delle maggiori differenze tra i risultati delle prestazioni sul campo (ad esempio da CrUX) e in laboratorio (ad esempio da Lighthouse) è la mancanza di input dell'utente. È qui che un periodo di tempo, l'ultima modalità di flusso utente, può essere utile.

Un periodo di tempo esegue i controlli di Lighthouse per un determinato periodo di tempo, che può includere o meno una navigazione. Questo è un ottimo modo per acquisire ciò che accade in una pagina durante le interazioni. Ad esempio, per impostazione predefinita Lighthouse misura il CLS durante il caricamento pagina, ma sul campo il CLS viene misurato dalla navigazione iniziale fino alla chiusura della pagina. Se le interazioni degli utenti sono l'attivatore di CLS, Lighthouse non sarebbe in grado di rilevare e aiutare a risolvere il problema.

Una normale navigazione di Lighthouse avrà un CLS pari a 0. Tuttavia, una volta fatto scorrere, la pagina subirà variazioni di layout problematiche e il valore CLS aumenterà.

Lo script seguente genererà un report sul flusso utente con entrambe le azioni per mostrare la differenza.

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.example.com/';
  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();

In questo modo viene generato un report che confronta una navigazione normale con un periodo di tempo che contiene sia una navigazione sia lo scorrimento successivo:

Un report sul flusso di Lighthouse che mostra un insieme di istantanee acquisite

Analizzando ogni passaggio, quello di sola navigazione mostra un CLS pari a 0. Ottimo sito!

Il report Lighthouse che copre solo la navigazione nelle pagine con tutte le metriche verdi

Tuttavia, il passaggio "Naviga e scorri" racconta una storia diversa. Al momento, solo Total Blocking Time e Cumulative Layout Shift sono disponibili nei periodi di tempo, ma i contenuti con caricamento lento in questa pagina riducono chiaramente il CLS del sito.

Il report Lighthouse che copre la Navigazione nelle pagine e lo scorrimento con un CLS non riuscito

In precedenza, Lighthouse non era in grado di identificare questo comportamento problematico del CLS, anche se quasi sicuramente si sarebbe verificato nell'esperienza degli utenti reali. I test delle prestazioni su interazioni basate su script migliorano notevolmente la fedeltà del lab.

In attesa di feedback

Le nuove API per i flussi utente di Lighthouse possono fare molte cose nuove, ma potrebbe essere ancora complicato misurare il tipo di scenari che gli utenti incontrano.

In caso di domande, contattaci nei forum di discussione di Lighthouse e segnala eventuali bug o suggerimenti nell'Issue Tracker.