---
title: "Lighthouse CIの使い方｜lighthouserc・assertの判定とGitHub Actions連携【@lhci/cli 0.15.1】"
url: "https://www.issoh.co.jp/tech/details/7542/"
published: 2025-07-03
updated: 2026-10-12
categories: ["CI/CD"]
publisher: "株式会社一創"
---

# Lighthouse CIの使い方｜lighthouserc・assertの判定とGitHub Actions連携【@lhci/cli 0.15.1】

Lighthouse CI（LHCI）は、プルリクエストやデプロイのたびにLighthouseを自動で走らせ、スコアや監査結果が基準を割ったらビルドを落とすためのツールです。npmパッケージ `@lhci/cli` の `lhci autorun` 1本で「計測（collect）→判定（assert）→保存（upload）」が回ります。

この記事では2026年10月2日時点の最新版 `@lhci/cli` 0.15.1 を前提に、`lighthouserc.json` の書き方、assertの判定規則、GitHub Actions・GitLab CIへの組み込み、結果の保存先を整理します。presetの中身はパッケージのソースで確認し、判定の挙動は手元で `lhci autorun` を3回実行して確かめました。

## まとめ：Lighthouse CI導入の要点

- **最新は @lhci/cli 0.15.1（2025年6月公開）**。同梱のLighthouseは12.6.1に固定されており、Lighthouse単体の最新13.5.0（2026年9月18日）とは版が違います。
- **最小構成**は `lighthouserc.json` に計測対象（`staticDistDir` か `url`）とassertのpresetを書き、`npx lhci autorun` を実行するだけです。計測回数の既定は3回。
- **presetだけではTBTの悪化でビルドは落ちません**。`total-blocking-time` はpresetでoffなので、性能の門番にするなら `categories:performance` や `total-blocking-time` を明示的にerrorで足します。
- **オプション無しのassertは「3回のうち最良値が0.9以上か」**で判定されます。ドキュメントは `minScore: 1` と書いていますが、0.15.1の実装の既定は0.9です。
- **temporary-public-storageは誰でも閲覧できる公開ストレージ**で、運営はGoogleではなくEris Ventures LLCです。社内ページや未公開URLのレポートは、filesystemか自前のLHCIサーバーへ保存します。
- GitHubのステータスチェックは `LHCI_GITHUB_APP_TOKEN`（GitHub App）か `LHCI_GITHUB_TOKEN`（`repo:status` スコープのPAT）で付きます。

## Lighthouse CIの仕組みと単体のLighthouseとの違い

ブラウザのDevToolsやPageSpeed Insightsで動かすLighthouseは、1回の計測結果を人が読むための道具です。Lighthouse CIはそれをCIに載せ、毎回同じ条件で複数回計測して、結果を基準値と機械的に比べます。コード変更で画像の最適化漏れや重いスクリプトが入ったとき、マージ前に検出できるのが導入する理由です。

コマンドは役割ごとに分かれていて、`autorun` がその3つをまとめて呼びます。

| コマンド               | 役割                  | 主な設定                                               |
| ------------------ | ------------------- | -------------------------------------------------- |
| `lhci collect`     | Lighthouseを実行し結果を保存 | `url`・`staticDistDir`・`numberOfRuns`               |
| `lhci assert`      | 基準と比べて合否を判定         | `preset`・`assertions`・`budgetsFile`                |
| `lhci upload`      | 結果を保存先へ送る           | `target`（lhci／temporary-public-storage／filesystem） |
| `lhci autorun`     | 上の3つを設定に応じて実行       | 子コマンドの設定を引き継ぐ                                      |
| `lhci server`      | 履歴と差分を見るダッシュボード     | `storage`（sqlite／mysql／postgres）                   |
| `lhci healthcheck` | 設定とChromeの有無を事前確認   | なし                                                 |

計測されるのはラボデータです。実ユーザーの体感（フィールドデータ）とは別物で、INPのように操作が要る指標はナビゲーション計測では取れません。指標ごとのラボとフィールドの扱いは[INPの基準値と3区間・改善手順](/tech/details/7543/)で、スコアの配点は[Lighthouseスコアの見方と改善方法](/column/details/2354/)で解説しています。

### 同梱Lighthouseの版：0.15.1は12.6.1固定

`@lhci/cli` 0.15.1の `package.json` は依存を `"lighthouse": "12.6.1"` と完全固定しています。Lighthouse本体はその後13系に進み、13.0.0で動作要件がNode.js 22.19以上に引き上げられています。一方LHCIのリリースは0.15.1（2025年6月）で止まっています。

このため、LHCIのスコアはChromeのDevToolsやPageSpeed Insightsで見る最新Lighthouseの結果と一致しないことがあります。13系で入った監査やカテゴリはLHCIでは計測されません。CIの値は「同じ版で前回と比べる」用途に限り、他ツールの点数と突き合わせないのが安全です。

## ローカルでの導入手順とlhci autorunの最小構成

12.6.1の動作要件はNode.js 18.20以上です。まず開発依存として入れます。`--save-exact` を付けないと `package.json` には `^0.15.1` で記録されるので、版を固定するなら付けます。

```
npm install -D --save-exact @lhci/cli@0.15.1
npx lhci --version   # 0.15.1
npx lhci healthcheck
```

設定ファイルはリポジトリ直下に置きます。`lighthouserc.json`・`.lighthouserc.json`・`lighthouserc.js`・`.lighthouserc.yml` などの名前が自動で読まれます。静的サイトなら、ビルド成果物のディレクトリを渡すだけで組み込みサーバーが立ちます。

```
{
  "ci": {
    "collect": {
      "staticDistDir": "./dist",
      "numberOfRuns": 3
    },
    "assert": {
      "preset": "lighthouse:recommended"
    },
    "upload": {
      "target": "filesystem",
      "outputDir": "./lhci-report"
    }
  }
}
```

計測対象の指定方法は3通りあり、アプリの形で選びます。

- `staticDistDir`：HTMLを書き出す静的サイト向け。対象URLを省くとHTMLを最大5件（`maxAutodiscoverUrls`）まで自動で拾います。`autorun` では `dist`・`build`・`out`・`public` の順に自動で探されます。
- `startServerCommand` と `url`：Next.jsのSSRなどサーバーが要るアプリ向け。起動ログに `listen` か `ready` が出るまで既定で10秒待ちます。`staticDistDir` とは併用しません。
- `url` のみ：ステージングなど既に動いている環境を測る場合。

`autorun` に子コマンドの設定をCLIで渡すときは、`lhci autorun --collect.numberOfRuns=5` のように必ず `=` でつなぎます。空白区切りは受け付けません。

## assertの書き方とpresetの選び方

assertは監査IDごとに `"監査ID": "レベル"` か `"監査ID": ["レベル", {オプション}]` で書きます。レベルは3段階で、`warn` は表示だけで終了コードを変えず、`error` だけがビルドを落とします。

### 判定条件とaggregationMethodの既定値

オプションを書かないassertの集計方法は `optimistic` で、「複数回のうち一番良い回」の値で判定されます。スコアの下限について、設定ドキュメントは既定を `minScore: 1`（満点）と書いています。しかし0.15.1の実装（`@lhci/utils/src/assertions.js`）は、`maxLength` も `maxNumericValue` も無いときに0.9を補います。実測のログでも、presetの監査は `expected: >=0.9` と表示されました。計測回数を増やすほど判定が甘くなる点にも注意してください。

| aggregationMethod | 使う値           | 向く場面            |
| ----------------- | ------------- | --------------- |
| `optimistic`（既定）  | 最も合格しやすい回     | 揺れやすい監査の誤検知を減らす |
| `pessimistic`     | 最も合格しにくい回     | 1回でも悪ければ落としたい   |
| `median`          | 監査値の中央値       | 数値指標の一般的な判定     |
| `median-run`      | 性能指標で代表とされた1回 | カテゴリスコアの判定      |

条件はスコアなら `minScore`（0〜1）、ミリ秒やバイトの実測値なら `maxNumericValue`、指摘件数なら `maxLength` を使います。カテゴリ全体は `categories:performance` のように `categories:` を前に付けます。

```
"assertions": {
  "categories:performance": ["error", {"minScore": 0.9, "aggregationMethod": "median-run"}],
  "largest-contentful-paint": ["error", {"maxNumericValue": 2500}],
  "total-blocking-time": ["error", {"maxNumericValue": 200}]
}
```

CLIで一時的に上書きするなら `lhci assert --preset=lighthouse:recommended --assertions.speed-index=off` の形です。`autorun` 経由で渡すときは `--assert.assertions.categories:performance=error` のように `--assert.` を前に付けます。

### 3つのpresetの中身

presetは `lighthouse:all`・`lighthouse:recommended`・`lighthouse:no-pwa` の3つです。0.15.1のソース（`@lhci/utils/src/presets/`）を読むと、ドキュメントの説明だけでは分からない点があります。

- **`all`**：ほぼ全監査をerrorにし、オプション無しなので実装上はスコア0.9以上を要求します（ドキュメントの説明は満点）。ただし `total-blocking-time`・`interaction-to-next-paint`・`resource-summary` などはoffです。
- **`recommended`**：`all` を引き継ぎ、FCP・LCP・CLS・Speed Indexなど揺れやすい指標をwarnに下げます。画像最適化や未使用JSの指摘は `maxLength: 0` のerrorで、1件でも出れば落ちます。
- **`no-pwa`**：`recommended` から `is-on-https` と `viewport` をoffにしただけです。ソースには「PWAはもう存在しないので削除すべきか」というTODOコメントが残っています。

Lighthouse 12でPWAカテゴリは削除されましたが、`is-on-https` と `viewport` は12.6.1でもBest Practicesの監査として残っています。`no-pwa` を選ぶとHTTPSとviewportの検査が黙って外れるので、今から始めるなら `recommended` を選び、外したい監査を個別にoffにします。

もう1つの落とし穴は、Performanceスコアで配点が最大（30%）のTBTがpresetではoffなことです。presetだけでは、メインスレッドを塞ぐスクリプトが入っても、未使用JavaScriptなど他のerror対象の監査に引っかからない限りビルドは通ります（次章の実測3）。

### リソース予算：budgetsFileとresource-summary

転送量やリクエスト数の上限は、`budgetsFile` でLighthouse形式の `budgets.json` を読むか、assertに `resource-summary:<種類>:size` ／ `:count` を書くかの2通りです。`budgetsFile` は他のassert設定と併用できません。presetと一緒に使うなら `resource-summary` 形式に書き換えます。単位も違い、`budgets.json` はKB、`resource-summary` の `maxNumericValue` はバイトです。

```
"resource-summary:script:size": ["error", {"maxNumericValue": 300000}],
"resource-summary:third-party:count": ["warn", {"maxNumericValue": 10}]
```

## 実測：最小ページにrecommendedを当てた3回の結果

presetの挙動を確かめるため、2026年10月2日に次の環境で `lhci autorun` を実行しました。`@lhci/cli` 0.15.1（Lighthouse 12.6.1）、ヘッドレスのChrome 154、Node.js 26.5.0、既定のモバイル設定（CPU 4倍スロットリングのsimulate）で、各ページ3回ずつ計測しています。

| 回 | ページの内容           | assert          | 終了コード | 主な結果                          |
| - | ---------------- | --------------- | ----- | ----------------------------- |
| 1 | h1と段落だけのHTML     | recommended     | 1     | `errors-in-console` 0点        |
| 2 | 1にfaviconを追加     | recommended＋3項目 | 0     | Performance 100               |
| 2 | 本文直後に300msの同期ループ | 同上              | 0     | FCP 約1.89秒・TBT 0〜22ms・warn 2件 |
| 3 | 同じループをload後に実行   | 同上              | 1     | TBT 1,118.5ms・Performance 77  |

**1回目は、Performance・Accessibility・SEOが満点なのに失敗しました**。原因は `/favicon.ico` の404がコンソールエラーとして記録されたことです。`errors-in-console` はpresetでerrorなので、faviconを置いていない検証用ページや、外部タグが404を出すページは初回から落ちます。2回目は `<link rel="icon" href="data:,">` を足しただけで通りました。

**同じ300msの処理でも、置き場所でTBTは0にも1秒超にもなります**。本文直後に置いたループは最初の描画（FCP）より前に終わるため、TBTの集計区間（FCP以降）に入りません。FCPが約0.7秒から約1.89秒へ遅れ、presetはFCPとSpeed Indexのwarnを出しただけでビルドは通りました。load後に動かすとTBTが1,118.5ms（3回の値は1,180.5／1,141.5／1,118.5）になり、明示的に足した `total-blocking-time` と `categories:performance` のassertで失敗しました。presetが出したのは `max-potential-fid` のwarnだけです。

ここから言えるのは、presetを入れただけの状態は「画像やCSSの指摘は厳しく、体感速度の悪化には甘い」という偏りを持つことです。性能を門番にするなら、TBTとカテゴリスコアのassertを自分で足してください。実行1と2・3の違いは表の「assert」列のとおりで、2・3で足した3項目は前章の `assertions` の例（`categories:performance` を `median-run` で0.9以上、LCP 2,500ms以下、TBT 200ms以下）と同じです。

## GitHub Actionsでの実行とステータスチェック

公式ドキュメントの例は `actions/checkout@v3` とNode.js 16のままです。2026年10月時点の現行版（checkout v7・setup-node v7、Node.js 24 LTS）に置き換えると次のようになります。`@lhci/cli` は `package.json` の開発依存で版を固定しておき、`npx` で呼びます。assertが失敗すればジョブが落ちるので、合否の判定はトークン無しでも働きます。PRにLHCIのステータスチェックを付けるには、次節のトークンに加えて `upload.target` をfilesystem以外にします。

```
name: Lighthouse CI
on:
  pull_request:
  push:
    branches: [main]
jobs:
  lhci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
        with:
          ref: ${{ github.event.pull_request.head.sha }}
      - uses: actions/setup-node@v7
        with:
          node-version: 24
          cache: npm
      - run: npm ci
      - run: npm run build
      - run: npx lhci autorun
        env:
          LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
```

`ref` にPRのheadコミットを渡すのは、LHCIがgitのハッシュや祖先コミットから比較対象を推定するためです。`pull_request` イベントの既定ではマージ用の一時コミットがチェックアウトされます。setup-nodeの入力やキャッシュの既定は[actions/setup-nodeのv7の入力とキャッシュ設定](/tech/details/17919/)にまとめています。

### ステータスチェックのトークン：GitHub AppかPATか

PRに合否のチェックを付けるトークンは2種類です。

- **GitHub App（推奨）**：`github.com/apps/lighthouse-ci` をリポジトリに入れ、表示されたトークンを `LHCI_GITHUB_APP_TOKEN` に設定します。Appを運営するのはEris Ventures LLCで、同社の利用規約への同意が前提です。
- **Personal Access Token**：`repo:status` スコープのトークンを `LHCI_GITHUB_TOKEN` に設定します。チェックは作成したユーザーの名義で付きます。

どちらもトークンを持つ人がステータスを書き込めるので、リポジトリのSecretsに置きます。置き場所の選び方は[GitHub ActionsのSecrets管理](/tech/details/16939/)を参照してください。なお `upload.target` がfilesystemのときはステータスチェックは付きません。

### treosh/lighthouse-ci-actionの入力と計測回数

CLIを自分で呼ばずに、Marketplaceの `treosh/lighthouse-ci-action`（最新12.6.2・2026年3月12日、Lighthouse 12.6系）を使う方法もあります。入力は `urls`（改行区切り）、`configPath`、`budgetPath`、`uploadArtifacts`、`temporaryPublicStorage`、`runs` などです。

注意点は `runs` の既定が1回なことです。CLIの `numberOfRuns` の既定3回より少ないため、揺れを均したいなら明示的に3以上にします。`uploadArtifacts: true` にするとレポートはワークフローのアーティファクトとして残り、保持期間はリポジトリ設定に従います（[GitHub Actionsのアーティファクト](/tech/details/16951/)）。

## GitLab CIでの実行

公式のGitLab CI例は次のとおりです。

```
image: cypress/browsers:node16.17.0-chrome106
lhci:
  script:
    - npm install
    - npm run build
    - npm install -g @lhci/cli@0.15.x
    - lhci autorun --upload.target=temporary-public-storage --collect.settings.chromeFlags="--no-sandbox" || echo "LHCI failed!"
```

そのまま写すと品質ゲートになりません。末尾の `|| echo "LHCI failed!"` がLHCIの失敗を握りつぶし、ジョブは常に成功します。ビルドを止めたいならこの部分を消します。イメージもNode.js 16・Chrome 106と古いので、Node.js 18.20以上とChromeを含む現行イメージに替えてください。`--no-sandbox` はコンテナ内のChromeを起動するために要りますが、公式もセキュリティ上のトレードオフを確認するよう注記しています。

## 結果の保存先：公開ストレージ・ファイル・LHCIサーバー

`upload.target` は `lhci`（既定）・`temporary-public-storage`・`filesystem` の3つです。何を測るかで選びます。

| target                   | 保存先                     | 公開範囲      | 向く場面            |
| ------------------------ | ----------------------- | --------- | --------------- |
| temporary-public-storage | Eris Ventures運営の公開ストレージ | 誰でも閲覧可    | OSSや公開済みサイトの試用  |
| filesystem               | `outputDir` にHTMLとJSON  | CIの成果物の範囲 | 社内ページ・履歴が要らない場合 |
| lhci                     | 自前のLHCIサーバー             | サーバーの設定次第 | 履歴の推移と差分を見たい場合  |

### temporary-public-storageの公開性と保持期間

サービス規約は、アップロードしたデータを「世界中の誰でも、いつでも、どんな理由でもアクセスできる公開情報」とし、保持期間を空き容量に応じて3日〜5週間としています。treoshのActionのREADMEは「7日後に自動削除」と書いていますが、運営者の規約の方が優先です。期間は一定ではないと考えてください。

レポートにはURL、スクリーンショット、読み込まれたリソースの一覧が入ります。ステージングや管理画面を測るなら、このtargetは使わないでください。`autorun` ではアップロード失敗は既定で警告に留まり、ビルドは落ちません（`failOnUploadFailure` で変更可）。

### LHCIサーバーの構築：DBとDocker・Basic認証

LHCIサーバーは結果の履歴をグラフで見せ、ビルド間の監査の差分を比べる画面を持ちます。保存先はsqlite・mysql・postgresqlのいずれかです。手元で試すなら次の1行で起動し、既定の `http://localhost:9001/` で開きます。

```
npm install -D @lhci/cli @lhci/server sqlite3
npx lhci server --storage.storageMethod=sql --storage.sqlDialect=sqlite --storage.sqlDatabasePath=./db.sql
```

Dockerなら公式レシピのイメージ `patrickhulce/lhci-server` を使います（`lhci/server` ではありません）。

```
docker container run --publish 9001:9001 --mount='source=lhci-data,target=/data' --detach patrickhulce/lhci-server
```

サーバーを立てたら手元で `lhci wizard` を実行してプロジェクトを作ります。発行されるのはビルドトークンと管理トークンの2つです。CIにはビルドトークンだけを `upload.token` か環境変数 `LHCI_TOKEN` で渡し、プロジェクトのデータを編集・削除できる管理トークンはCI環境に置きません。LHCI設定の `upload` は、`target` を `lhci` に、`serverBaseUrl` をサーバーのURLに書き換えます（`serverBaseUrl` は `target=lhci` のとき必須）。運用で押さえる点は3つあります。

- **既定では閲覧制限が無い**：既存プロジェクトへのアップロードにはビルドトークン、編集・削除には管理トークンが要りますが、HTTPで到達できる人は誰でもレポートを閲覧でき、新しいプロジェクトも作れます。サーバー側に `basicAuth.username` と `basicAuth.password` を設定し、upload側にも同じ値を渡します。
- **オリジンを丸ごと使う前提**：サブパスで動かすなら、公式のプロキシ設定例（lhci-server-vpn-proxy）に従います。
- **ドキュメントの要件表記が古い**：要件は「Node v16 LTS」のままですが、同梱のLighthouse 12.6.1はNode.js 18.20以上を求めます。

## Lighthouse CIを入れない方がよい場面と運用の注意

LHCIは「同じ条件で前回より悪くなったか」を見る道具で、ユーザーの体感を保証するものではありません。次の場面では導入より先に別の手段を選びます。

- **実ユーザーの遅さが問題になっている**：Search Consoleの評価はCrUXのフィールドデータで決まります。先に[コアウェブバイタルの3指標](/column/details/3761/)を実測で確認し、LHCIは再発防止に回します。
- **ログインが必要なページが中心**：`puppeteerScript` で認証を通せますが、セッション管理のコードを保守し続けることになります。
- **共有ランナーで絶対値を判定したい**：ランナーの負荷で数値が揺れます。`maxNumericValue` は余裕を持って置き、`median` で判定します。

導入する場合も、既存の違反が残るサイトで最初から `lighthouse:all` を当てると、ほぼ全監査がerrorなので初回からビルドが落ち続けます。公式も、スコアがまだ低いサイトではassertを後回しにするよう勧めています。まずfilesystemで数週間の値を集め、実際の分布を見てから閾値を決める順番が現実的です。

## よくある質問

### Lighthouse CIとLighthouseの違いは何ですか？

Lighthouseは1ページを1回監査するツールで、Lighthouse CIはそれをCIで複数回実行し、assertで合否を判定してビルドを止める仕組みです。計測エンジンは同じですが、LHCI 0.15.1が使うLighthouseは12.6.1に固定されています。

### @lhci/cliの最新バージョンはいくつですか？

2026年10月2日時点で0.15.1（2025年6月公開）です。同梱のLighthouseは12.6.1で、Lighthouse単体の最新13.5.0とは異なります。`npm install -D --save-exact @lhci/cli@0.15.1` で版を固定して使います。

### categories:performanceで閾値を指定するには？

assertに `"categories:performance": ["error", {"minScore": 0.9}]` を書きます。CLIなら `lhci assert --assertions.categories:performance=error`、`autorun` 経由なら `--assert.` を前に付けます。閾値や集計方法まで指定するなら設定ファイルに書く方が確実です。複数回計測では `aggregationMethod` に `median-run` を指定すると代表の1回で判定されます。

### GitLab CIでLighthouse CIを動かすには？

Chromeを含むNode.jsイメージで `npm install -g @lhci/cli@0.15.x` を入れ、`lhci autorun --collect.settings.chromeFlags="--no-sandbox"` を実行します。公式例の末尾にある `|| echo "LHCI failed!"` は失敗を握りつぶすので、品質ゲートにするなら削除します。

### Lighthouse CIサーバーは必須ですか？

必須ではありません。合否判定だけならfilesystemやtemporary-public-storageで足ります。サーバーが要るのは、スコアの推移をグラフで追う場合と、ビルド間の監査結果の差分を画面で比べたい場合です。

## 関連記事

- [Lighthouseスコアの見方と改善方法｜Best Practices・SEOの配点と5カテゴリ](/column/details/2354/)
- [コアウェブバイタルとは？3指標（LCP・INP・CLS）の基準と改善方法【2026年版】](/column/details/3761/)
- [INPとは？Core Web Vitalsの応答性指標の基準値と3区間・改善手順](/tech/details/7543/)
- [actions/setup-nodeとは｜v7の入力・キャッシュ設定とv5以降の既定変更](/tech/details/17919/)
- [GitHub ActionsのSecrets管理｜置き場所の選定と漏えい経路・OIDC移行の判断](/tech/details/16939/)

---

出典: [Lighthouse CIの使い方｜lighthouserc・assertの判定とGitHub Actions連携【@lhci/cli 0.15.1】](<https://www.issoh.co.jp/tech/details/7542/>)（株式会社一創）
