複数ページをまとめてLighthouseで検証する

## Lighthouseについて

皆さん、Lighthouseは使っていますか？
Google Chrome上で簡単に実行できて、SEOやパフォーマンス、ユーザビリティのチェックまで出来て便利ですね。

![ligthouse.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426622/b42d591b-8221-a3c9-395b-432206527f27.png)

Lighthouseで検出できる課題や改善点をどこまで追求するか、スコアを追い求めるかは案件によって答えが異なると思います。

内部向け業務システムであれば、よっぽどパフォーマンスが悪く、使い勝手に影響しているなどではなければ、それほど注意深くみる必要はないと思いますし、一般的なWebサイトでのレイアウトシフト対応も修正にかかるコストと効果のバランスがとれるのか、というのは意思決定時に注意すべきです。

一方で、案件によってはLighthouseのスコアありきの要求もあるでしょう。

例えば、全ページにおいて、Lighthouseの「ユーザ補助」が100点である要求だった場合、ひとつひとつを手作業で確認するには手間がかかります。
[Lighthouseはnpmでも提供](https://www.npmjs.com/package/lighthouse)されているため、このような場合はCLIから実行を想定すると良いでしょう。

## ワンライナーでエラーの有無を確認

`npm install -g lighthouse` でグローバルインストールすると、`lighthouse`コマンドが利用できるようになります。

例えば、 https://example.com/ で「ユーザー補助（accessibility）」のみを検証する場合は下記のように実行できます。

```bash
lighthouse https://example.com/ --only-categories=accessibility --disable-full-page-screenshot --quiet --chrome-flags="--headless"  --output=json
```

結果のJSONから `categories.accessibility.score` のみを抽出したいので、下記のように`jq`を用いて抽出しましょう。

```bash
lighthouse https://example.com/ --only-categories=accessibility --disable-full-page-screenshot --quiet --chrome-flags="--headless"  --output=json | jq .categories.accessibility.score
```

そうすると、`0.86`のように結果を得ることができます。

シェルスクリプトとして呼び出す際にはエラーの有無だけを確認して、修正する際には詳細の修正箇所を確認するため、Chrome上のLighthouseを用いると便利です。

スコアが100点だった場合は`OK`それ以外を、`Has accessibility error`と出力してみましょう。

```bash
{ [ `lighthouse https://example.com/ --only-categories=accessibility --disable-full-page-screenshot --quiet --chrome-flags="--headless"  --output=json | jq .categories.accessibility.score` = "1" ]  } && echo "OK" || echo "Has accessibility error"
```

複数ページを検証したい場合は、下記のようにシェルスクリプトにまとめて記載すると良いでしょう。

```bash
{ [ `lighthouse https://test.example.com/ --only-categories=accessibility --disable-full-page-screenshot --quiet --chrome-flags="--headless"  --output=json | jq .categories.accessibility.score` = "1" ]  } && echo "OK" || echo "Has accessibility error"
{ [ `lighthouse https://test.example.com/page1/ --only-categories=accessibility --disable-full-page-screenshot --quiet --chrome-flags="--headless"  --output=json | jq .categories.accessibility.score` = "1" ]  } && echo "OK" || echo "Has accessibility error"
{ [ `lighthouse https://test.example.com/page1/child1/ --only-categories=accessibility --disable-full-page-screenshot --quiet --chrome-flags="--headless"  --output=json | jq .categories.accessibility.score` = "1" ]  } && echo "OK" || echo "Has accessibility error"
```

## ややこしいワンライナーにしなくても

ここまでくると、ワンライナーに拘らなくても良い気がしてきますね。
`urls.txt`に対象のURLを記載してまとめて検証できるNode.jsのプログラムにしてみましょう。

```javascript
import fs from 'fs';
import lighthouse from 'lighthouse';
import * as chromeLauncher from 'chrome-launcher';

const urlsFile = 'urls.txt';

async function runLighthouse(url) {
  const chrome = await chromeLauncher.launch({ chromeFlags: ['--headless'] });
  const options = {
    logLevel: 'error',
    output: 'json',
    onlyCategories: ['accessibility'],
    port: chrome.port,
  };
  const runnerResult = await lighthouse(url, options);

  await chrome.kill();

  return runnerResult.lhr.categories.accessibility.score;
}

async function main() {
  const urls = fs.readFileSync(urlsFile, 'utf-8').split('\n').filter(Boolean);
  let allPassed = true;

  for (const url of urls) {
    try {
      const score = await runLighthouse(url);
      console.log(`${url}: ${score}`);
      if (score !== 1) {
        allPassed = false;
      }
    } catch (error) {
      console.error(`Error checking ${url}:`, error);
      allPassed = false;
    }
  }

  process.exit(allPassed ? 0 : 1);
}

main();
```

### 実行イメージ

```bash
% node checkAccessibility.js
https://www.add-more.co.jp/: 0.93
https://www.add-more.co.jp/services/: 0.93
https://www.add-more.co.jp/works/: 0.92
https://www.add-more.co.jp/works/web/icnet/: 0.93
```

これで、日々の修正で問題が発生していないかまとめて簡単にチェックできるようになりました。
`accessibility.score` が満点であることが必須なプロジェクトではGitHub ActionsなどのCIに組み込んでも良いかもしれません。

要件に応じて、パフォーマンスやSEOについても併せて確認するようにプログラムを修正しても良いでしょう。

---

株式会社add moreではこのように確認に手間がかかることを自動化したり、改善しながら制作や開発を行うエンジニアを募集しています。
ご興味のある方は[コーポレートサイト](https://www.add-more.co.jp/recruit/engineer/)または[Wantedly](https://www.wantedly.com/companies/add-more)からご応募ください。