• #lighthouse
  • #performance
  • #ci
  • #testing

Lighthouse CI ローカルセットアップガイド

Lighthouse CIは、Lighthouseを継続的に実行し、結果の保存・取得・アサーションを簡単に行うためのツールスイートです。

インストール

グローバルインストール

npm install -g @lhci/cli

バージョンを指定する場合:

npm install -g @lhci/cli@0.15.x

プロジェクトローカルインストール

プロジェクト内でのみ使用する場合:

npm install --save-dev @lhci/cli

または pnpm の場合:

pnpm add -D @lhci/cli

設定ファイルの作成

プロジェクトルートに設定ファイルを作成します。

ファイル拡張子の注意点

重要: package.json"type": "module" が設定されているプロジェクトでは、設定ファイルを .cjs 拡張子にする必要があります。

# ESモジュールプロジェクトの場合
lighthouserc.cjs  # ← .cjs を使用

# CommonJSプロジェクトの場合
lighthouserc.js   # ← .js でOK

.js のまま実行すると以下のエラーが発生します:

ReferenceError: module is not defined in ES module scope
This file is being treated as an ES module because it has a '.js' file extension
and 'package.json' contains "type": "module".
To treat it as a CommonJS script, rename it to use the '.cjs' file extension.

基本設定(一時的なパブリックストレージを使用)

module.exports = {
  ci: {
    upload: {
      target: 'temporary-public-storage',
    },
  },
};

レポートは7日間保存されます。

静的サイトの設定

ビルド済みの静的ファイルがある場合:

module.exports = {
  ci: {
    collect: {
      staticDistDir: './dist',
    },
    upload: {
      target: 'temporary-public-storage',
    },
  },
};

開発サーバーを使用する設定

Nuxt、Next.js などの開発サーバーを起動して測定する場合:

module.exports = {
  ci: {
    collect: {
      startServerCommand: 'npm run start',
      url: ['http://localhost:3000/'],
    },
    upload: {
      target: 'temporary-public-storage',
    },
  },
};

複数URLを測定する設定

module.exports = {
  ci: {
    collect: {
      startServerCommand: 'npm run start',
      url: [
        'http://localhost:3000/',
        'http://localhost:3000/about',
        'http://localhost:3000/blog',
      ],
      numberOfRuns: 3, // 各URLに対する実行回数(デフォルト: 3)
    },
    upload: {
      target: 'temporary-public-storage',
    },
  },
};

Lighthouse CI の実行

自動実行(推奨)

lhci autorun

autorun は以下を自動的に実行します:

  1. サーバーの起動(設定されている場合)
  2. 各URLに対してLighthouseを複数回実行
  3. 中央値のレポートを特定
  4. レポートをアップロード

個別コマンドの実行

# Lighthouseの実行のみ
lhci collect

# アサーションの実行
lhci assert

# レポートのアップロード
lhci upload

アサーション(品質チェック)の設定

ビルド時にパフォーマンス閾値をチェックするには、assert セクションを追加します。

推奨プリセットを使用

module.exports = {
  ci: {
    collect: {
      startServerCommand: 'npm run start',
      url: ['http://localhost:3000/'],
    },
    assert: {
      preset: 'lighthouse:recommended',
    },
    upload: {
      target: 'temporary-public-storage',
    },
  },
};

カスタムアサーション

module.exports = {
  ci: {
    collect: {
      startServerCommand: 'npm run start',
      url: ['http://localhost:3000/'],
    },
    assert: {
      assertions: {
        'categories:performance': ['warn', { minScore: 0.9 }],
        'categories:accessibility': ['error', { minScore: 1 }],
        'categories:best-practices': ['warn', { minScore: 0.9 }],
        'categories:seo': ['warn', { minScore: 0.9 }],
      },
    },
    upload: {
      target: 'temporary-public-storage',
    },
  },
};

アサーションレベル

レベル動作
off失敗を無視
warn標準エラー出力に警告をログ
error非ゼロの終了コードでビルドを失敗させる

ローカルでの実行例

1. 開発サーバーを使用する方法(推奨)

最もシンプルな方法です。開発サーバーに対してLighthouseを実行します。

lighthouserc.cjs:

module.exports = {
  ci: {
    collect: {
      startServerCommand: 'pnpm dev',
      startServerReadyPattern: 'Local:',
      startServerReadyTimeout: 60000,
      url: ['http://localhost:3000/'],
      numberOfRuns: 3,
    },
    assert: {
      assertions: {
        'categories:performance': ['warn', { minScore: 0.8 }],
        'categories:accessibility': ['warn', { minScore: 0.9 }],
        'categories:best-practices': ['warn', { minScore: 0.9 }],
        'categories:seo': ['warn', { minScore: 0.9 }],
      },
    },
    upload: {
      target: 'temporary-public-storage',
    },
  },
};

実行:

npx lhci autorun

注意: 開発サーバーでの測定は本番環境より低いスコアになることがあります。

2. Cloudflare Pages プロジェクトの場合(wrangler使用)

Nitroプリセットが cloudflare-pages の場合、pnpm preview は内部で wrangler を起動します。この場合、wrangler を直接使用する方法が確実です。

lighthouserc.cjs:

module.exports = {
  ci: {
    collect: {
      startServerCommand: 'npx wrangler pages dev dist --port 8788',
      startServerReadyPattern: 'Ready on',
      startServerReadyTimeout: 60000,
      url: ['http://localhost:8788/'],
      numberOfRuns: 3,
    },
    assert: {
      assertions: {
        'categories:performance': ['warn', { minScore: 0.8 }],
        'categories:accessibility': ['warn', { minScore: 0.9 }],
        'categories:best-practices': ['warn', { minScore: 0.9 }],
        'categories:seo': ['warn', { minScore: 0.9 }],
      },
    },
    upload: {
      target: 'temporary-public-storage',
    },
  },
};

実行手順:

# 先にビルド
pnpm build

# Lighthouse CI 実行
npx lhci autorun

3. pnpm preview が動かない場合

Cloudflare Pages プリセットで pnpm preview を使うと、以下のようなエラーが発生することがあります:

Error: Could not resolve "worker_threads"
The package "worker_threads" wasn't found on the file system but is built into node.
- Add the "nodejs_compat" compatibility flag to your project.

この場合は以下のいずれかで対処します:

  1. 開発サーバーを使う(上記「方法1」)
  2. wrangler を直接使う(上記「方法2」)
  3. wrangler.toml に compatibility_flags を追加:
compatibility_flags = ["nodejs_compat"]

4. 結果の確認方法

コンソールで一覧確認

manifest.json にはすべてのページのスコアが保存されます。一覧表示用のスクリプトを使うと便利です:

pnpm lighthouse:summary

出力例:

📊 Lighthouse CI レポートサマリー

──────────────────────────────────────────────────────────────────────────────────────────
URL                                                   Perf    A11y      BP     SEO
──────────────────────────────────────────────────────────────────────────────────────────
/                                                       42     100      96     100
/about                                                  72     100     100     100
/blog                                                   29      95     100     100
──────────────────────────────────────────────────────────────────────────────────────────
平均                                                      48      98      99     100

📁 HTMLレポート: .lighthouseci/reports/

⚠️  パフォーマンスが低いページ:
   - / (42)
   - /blog (29)

HTMLレポートを開く

個別のHTMLレポートは .lighthouseci/reports/ フォルダに保存されます。ブラウザで直接開くことができます。

または lhci open コマンドでレポートを開けます:

pnpm lighthouse:open

出力先の設定

ローカル保存(オフラインで確認可能):

upload: {
  target: 'filesystem',
  outputDir: './.lighthouseci/reports',
}

一時的なパブリックストレージ(URL共有可能、7日間保存):

upload: {
  target: 'temporary-public-storage',
}

5. 実行結果の例

実行後、コンソールにレポートURLが表示されます:

✅ .lighthouseci/ directory writable
✅ Configuration file found
✅ Chrome installation found
⚠️  GitHub token not set

Healthcheck passed!

Running Lighthouse 3 time(s) on http://localhost:3000/
Run #1...done.
Run #2...done.
Run #3...done.

Done running Lighthouse!

Uploading median LHR of http://localhost:3000/...success!
Open the report at https://storage.googleapis.com/lighthouse-infrastructure.appspot.com/reports/xxxxx.report.html

本番環境の測定

開発サーバーでの測定はオーバーヘッドがあり、スコアが低くなります。正確な測定には本番環境を使いましょう。

方法1: デプロイ済みの本番URLを直接測定(推奨)

最も正確な方法です。実際の本番環境をそのまま測定します。

lighthouserc.cjs:

module.exports = {
  ci: {
    collect: {
      // サーバー起動不要 - 本番URLを直接指定
      url: [
        'https://your-site.example.com/',
        'https://your-site.example.com/about',
        'https://your-site.example.com/blog',
      ],
      numberOfRuns: 3,
    },
    assert: {
      assertions: {
        'categories:performance': ['warn', { minScore: 0.8 }],
        'categories:accessibility': ['warn', { minScore: 0.9 }],
        'categories:best-practices': ['warn', { minScore: 0.9 }],
        'categories:seo': ['warn', { minScore: 0.9 }],
      },
    },
    upload: {
      target: 'filesystem',
      outputDir: './.lighthouseci/reports',
    },
  },
};

実行:

pnpm lighthouse

メリット: CDN、キャッシュ、圧縮など本番環境の最適化がすべて反映される

方法2: ローカルで本番ビルドを測定

デプロイ前に本番に近い状態で確認したい場合。

# 1. 本番ビルド
pnpm build

# 2. wrangler で本番環境をシミュレート
npx wrangler pages dev dist --port 8788

lighthouserc.cjs:

module.exports = {
  ci: {
    collect: {
      // wrangler が起動済みの場合、startServerCommand は不要
      url: [
        'http://localhost:8788/',
        'http://localhost:8788/about',
        'http://localhost:8788/blog',
      ],
      numberOfRuns: 3,
    },
    // ...
  },
};

開発サーバー vs 本番環境の比較例

ページ開発サーバー本番環境
/4296
/about7298
/blog2943

トップページは 42 → 96 と大幅に改善されます。

トラブルシューティング

サーバーが起動しない

startServerReadyPattern を設定して、サーバーの起動完了を正しく検出できるようにします:

collect: {
  startServerCommand: 'npm run start',
  startServerReadyPattern: 'ready|listening|started',
  startServerReadyTimeout: 30000, // 30秒のタイムアウト
}

Chromeが見つからない

Lighthouse CIはChrome/Chromiumを必要とします。インストールされていることを確認してください。

ポートが使用中

別のポートを使用するように設定を変更します:

collect: {
  startServerCommand: 'PORT=4000 npm run start',
  url: ['http://localhost:4000/'],
}

参考リンク