Lighthouse のユーザーフロー

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

Brendan Kenny
Brendan Kenny

Lighthouse は、最初のページ読み込み時にパフォーマンスやベスト プラクティスをテストできる優れたツールです。しかしこれまで、Lighthouse を使用してページ全体の他の要素を分析することは困難でした。たとえば、次のような点です。

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

そのため、Lighthouse では重要な情報を見落とす可能性があります。Core Web Vitals は、空のキャッシュを含むページだけでなく、すべてのページの読み込みに基づいています。また、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 レポートが表示されます。

<ph type="x-smartling-placeholder">
</ph> 単一のナビゲーションを示す 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();

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

<ph type="x-smartling-placeholder">
</ph> パフォーマンス スコアが高い「コールド」と「ウォーム」の 2 つのナビゲーションが表示されている Lighthouse フローレポート
ライブレポートを見る

コールドロードとウォームロードを組み合わせることで、実際のユーザーが経験していることの全体像を把握できます。サイトの場合、ユーザーが 1 回の訪問で多くのページを読み込む場合、このフィールドを使用すると、ユーザーが実際に体験している状況を確認できます。

スナップショット

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

この例では、Squoosh 内の [Advanced Settings] の新しい UI が Lighthouse の自動チェックに合格していることを確認したいとします。これらの設定は、画像が読み込まれて、オプション メニューが展開されて詳細設定が表示されている場合にのみ表示されます。

<ph type="x-smartling-placeholder">
</ph> 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();

その結果、おおむね良好な結果が得られているものの、ユーザー補助の基準を手動で確認しなければならない場合があります。

<ph type="x-smartling-placeholder">
</ph> 取得された一連のスナップショットを示す Lighthouse フローレポート
ライブレポートを見る

期間

現場(CrUX など)とラボ(Lighthouse など)のパフォーマンス結果に大きな違いは、ユーザー入力が不足していることです。このような場合は、タイムスパン(最後のユーザーフロー モード)が役立ちます。

Lighthouse の監査は一定期間にわたって実施されます。これにはナビゲーションが含まれることも、含まれないこともあります。これは、操作中にページで何が起こっているかを把握するのに最適な方法です。たとえば、Lighthouse のデフォルトでは、ページの読み込み時に CLS が測定されますが、フィールドでは、最初のナビゲーションからページが閉じるまで CLS が測定されます。ユーザーの操作が CLS のトリガーである場合、Lighthouse ではこの原因を捕捉して修正することは不可能でした。

こちらのテストサイトでは、スクロール中にスペースを確保せずに記事に挿入される広告をシミュレートします。長いカード群では、スロットがビューポートに入るとときどき赤い正方形が追加されます。この赤い正方形のスペースは確保されていなかったので、その下にあるカードが邪魔にならないようにシフトし、レイアウト シフトが生じています。

通常の Lighthouse ナビゲーションの場合、CLS は 0 になります。しかし、スクロールすると、ページのレイアウト シフトが問題となり、CLS 値が増加します。

<ph type="x-smartling-placeholder">
</ph>
デモサイトを試す

次のスクリプトは、両方のアクションを含むユーザーフロー レポートを生成し、違いを示します。

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

これにより、通常のナビゲーションと、ナビゲーションとその後のスクロールの両方を含む期間を比較するレポートが生成されます。

<ph type="x-smartling-placeholder">
</ph> 取得された一連のスナップショットを示す Lighthouse フローレポート
ライブレポートを見る

各ステップを詳しく見ていくと、ナビゲーションのみのステップでは CLS が 0 になっています。素晴らしいサイトです。

ページ ナビゲーションのみを含み、緑色の指標がすべて含まれている Lighthouse レポート

ただし「ナビゲーションとスクロール」の異なるストーリーが展開されます。現在、タイムスパンで利用できるのは、合計ブロック時間と Cumulative Layout Shift のみですが、このページの遅延読み込みのコンテンツは、明らかにサイトの CLS を奪っています。

CLS の失敗とともにページのナビゲーションとスクロールについて説明する Lighthouse レポート

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

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

Lighthouse の新しいユーザーフロー API を使用すると、多くの新しいことを実現できますが、ユーザーが遭遇するシナリオの測定は依然として複雑な場合があります。

ご質問は Lighthouse ディスカッション フォーラムまでお寄せください。バグや提案については、Issue Tracker でお知らせください。