Lighthouse のユーザーフロー

ユーザーフロー全体にわたってパフォーマンスとベスト プラクティスを測定する新しい Lighthouse API をお試しください。

ブレンダン・ケニー(Brendan Kenny)氏
Brendan Kenny

Lighthouse は、最初のページ読み込み時にパフォーマンスやおすすめの方法をテストするのに適したツールです。しかし、従来から、Lighthouse を使用してページに関する次のような他の側面を分析することは困難でした。

  • ページがウォーム キャッシュで読み込まれる
  • Service Worker が有効になっているページ
  • 潜在的なユーザー操作を考慮する

つまり、Lighthouse では重要な情報を見落とす可能性があります。ウェブに関する主な指標は、キャッシュが空のページだけでなく、すべてのページ読み込みに基づきます。また、Cumulative Layout Shift(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();

これは最もシンプルなフローです。レポートを開くと、1 つのステップだけを含む概要ビューが表示されます。そのステップをクリックすると、そのナビゲーションに関する従来の Lighthouse レポートが表示されます。

1 つのナビゲーションを示す Lighthouse のフローレポート
レポートをライブで見る

Lighthouse では一般的ですが、このページはキャッシュまたはローカル ストレージが最初にクリアされた状態で読み込まれます。しかし、実際にサイトを訪れるユーザーは、コールド キャッシュとウォーム キャッシュが混在しており、このようなコールド読み込みと、ウォーム キャッシュでページに戻ったユーザーのパフォーマンスに大きな差が生じることがあります。

ウォーム負荷のキャプチャ

このスクリプトに 2 つ目のナビゲーションを追加することもできます。ここでは、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();

その結果、フローレポートは次のようになります。

2 つのナビゲーション(コールド ナビゲーションとウォーム ナビゲーション)を示す Lighthouse のフローレポート(パフォーマンス スコアが高い方)
レポートをライブで見る

コールド ロードとウォーム ロードを組み合わせることで、実際のユーザーが経験していることの全体像を把握できます。ユーザーが 1 回の訪問で多数のページを読み込むようなサイトでは、この機能によって、ユーザーが実際に体験している内容をより現実的に把握できます。

スナップショット

スナップショットは、Lighthouse の監査を特定の時点で実行する新しいモードです。通常の Lighthouse の実行とは異なり、ページは再読み込みされません。これにより、ページを設定して、そのままの状態(プルダウンを開いた状態やフォームの一部に入力した状態など)でテストできるようになります。

この例では、Squoosh 内の詳細設定の新しい UI の一部が、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 レポート: ページ ナビゲーションのみ、すべての緑色の指標を表示

しかし、「移動とスクロール」のステップは別の話になります。現在、タイムスパンで利用できるのは Total Blocking Time と Cumulative Layout Shift のみですが、このページの遅延読み込みコンテンツによって、サイトの CLS が明確にタンクされます。

失敗した CLS が表示されたページ ナビゲーションとスクロールに関する Lighthouse レポート

これまで Lighthouse では、問題のある CLS の動作を特定できませんでしたが、実際のユーザー エクスペリエンスにはほぼ確実に表示されます。スクリプトによる操作のパフォーマンス テストにより、ラボの忠実度が大幅に向上します。

フィードバックをお待ちしています

Lighthouse の新しいユーザーフロー API では、さまざまな新しいことを行えますが、ユーザーが直面するシナリオを測定するのはやはり複雑な作業です。

ご不明な点がございましたら、Lighthouse のディスカッション フォーラムでお問い合わせください。また、バグやご提案がございましたら、Issue Tracker でお知らせください。