新しい Lighthouse API を試して、ユーザー フロー全体のパフォーマンスとベスト プラクティスを測定しましょう。
Lighthouse は、ページの初回読み込み時のパフォーマンスとベスト プラクティスをテストするのに最適なツールです。ただし、従来 Lighthouse では、ページのライフサイクルの他の側面(次のような側面)を分析することは困難でした。
- キャッシュが温まっている状態でページが読み込まれる
- Service Worker が有効になっているページ
- ユーザーの潜在的な操作を考慮する
そのため、Lighthouse では重要な情報が見落とされてしまう可能性があります。Core Web Vitals は、キャッシュが空のページの読み込みだけでなく、すべてのページの読み込みに基づいています。また、Cumulative Layout Shift(CLS)などの指標は、ページが開いている間ずっと測定できます。
Lighthouse に、ページのライフサイクル内の任意の時点でラボテストを実行できる新しいユーザーフロー API が追加されました。Puppeteer は、ページの読み込みをスクリプト化し、合成ユーザー操作をトリガーするために使用されます。Lighthouse は複数の方法で呼び出して、操作中の重要な分析情報を取得できます。つまり、ページの読み込み中とページの操作中にパフォーマンスを測定できます。ユーザー補助チェックは CI で実行できます。最初のビューだけでなく、購入手続きフローの深い部分でも実行して、リグレッションがないことを確認できます。
動作するユーザーフローを実現するために記述された Puppeteer スクリプトであれば、ほとんどのスクリプトに Lighthouse を任意の位置に挿入して、パフォーマンスとベスト プラクティスを測定できます。このチュートリアルでは、ユーザーフローのさまざまな部分(ナビゲーション、スナップショット、期間)を測定できる新しい Lighthouse モードについて説明します。
セットアップ
user flow 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 でページの読み込みをキャプチャするスクリプトを作成するには:
- Puppeteer を使用してブラウザを開きます。
- Lighthouse ユーザーフローを開始します。
- ターゲット 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 レポートが表示されます。
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();
生成されたフロー レポートは次のようになります。
コールド ロードとウォーム ロードを組み合わせることで、実際のユーザーがどのような動作をしているか、より詳細に把握できます。ユーザーが同じアクセスで多くのページを読み込むサイトでは、ユーザーが実際にどのようなエクスペリエンスをしているかをよりリアルに把握できます。
スナップショット
スナップショットは、Lighthouse 監査を 1 つの時点で実行する新しいモードです。通常の Lighthouse 実行とは異なり、ページは再読み込みされません。これにより、ページをセットアップして、その状態(プルダウンが開いている、フォームが部分的に入力されているなど)でテストできるようになります。
この例では、Squoosh の詳細設定の新しい UI が Lighthouse の自動チェックに合格することを確認します。これらの設定は、画像が読み込まれ、オプション メニューが開いて詳細設定が表示されている場合にのみ表示されます。
このプロセスは 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();
生成されたレポートでは、結果は概ね良好ですが、手動で確認が必要なユーザー補助の基準がいくつかある可能性があります。
期間
現場(CrUX など)とラボ(Lighthouse など)でのパフォーマンス結果の最大の違いの 1 つは、ユーザー入力がないことです。このような場合に役立つのが、期間(最後のユーザー フロー モード)です。
期間は、一定の期間にわたって 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();
これにより、通常のナビゲーションと、その後のナビゲーションとスクロールの両方を含む期間を比較するレポートが生成されます。
各ステップを詳しく見ると、ナビゲーション専用のステップの CLS は 0 です。素晴らしいサイトですね。
ただし、「移動とスクロール」の手順は異なります。現在、期間で利用できる指標は Total Blocking Time と Cumulative Layout Shift のみですが、このページの遅延読み込みコンテンツは、サイトの CLS を明らかに低下させています。
以前は、Lighthouse ではこの問題のある CLS の動作を特定できませんでしたが、実際のユーザー エクスペリエンスではほぼ確実に問題となっていました。スクリプトによるインタラクションのパフォーマンス テストを行うと、ラボの忠実度が大幅に向上します。
フィードバックを探す
Lighthouse の新しいユーザーフロー API は多くの新しいことを行えますが、ユーザーが遭遇するシナリオを測定するのは複雑な場合があります。
ご不明な点がございましたら、Lighthouse のディスカッション フォーラムでお問い合わせください。バグや提案については、Issue Tracker からご報告ください。