2023.03.23[Thu]

PageSpeedInsightsをAPIで実行する

  • パフォーマンス

目次

Webエンジニアの茄子です。
ウェブサイトのパフォーマンス計測に欠かせないPageSpeedInsightsですが、実行するのが手間だったり、計測結果にばらつきがあるため、そのままだと大まかな現状を知る以上に用いるには少々厳しいと思います。
本記事では、APIで実行することでこれらを軽減することを目指します。

PageSpeedInsightsおさらい

(既に充分知っている方は飛ばしてください。)

PageSpeedInsightsは、Googleが提供するWebサイトのパフォーマンス計測ツールです。
Web Vitalsをはじめとして、画像やJavascriptの最適化が充分になされているかどうかを分析できます。また速度以外にも、SEOフレンドリーであるかどうか・アシスト機能が考慮されているか等を検査してくれます。

Google Chromeの機能として、開発者ツールからLighthouseが利用できますが、その場合は実行する環境が自身のPC、及び接続環境になるため、結果の一貫性が保たれません。対して、PageSpeedInsightsはLighthouseをスペックが一定のGoogleのサーバーで実行した結果であるためより一貫性のある結果を期待できます。また、PageSpeedInsightsではGoogleが収集している実際のUXレポート(CrUX)を元にした実環境データも出してくれます。リクエストによって行われる分析データをLab Data、後者のUXレポート由来のデータを Field Data といいます。

登録等は必要なく、公開されているウェブサイトのURLを入力することで分析が可能ですので、複数のウェブサイトの比較も可能です。

結果の例

準備

公式Doc : https://developers.google.com/speed/docs/insights/v5/get-started?hl=ja

まず、jq が入っていない場合はインストールしておいてください。( https://stedolan.github.io/jq/download/ )

APIキーは、今回の作成例では最終的に1秒に複数回にはならないため無くても構いませんが、開発時にキーの有無を気にしなくて良くなるという点では取得しておくのをおすすめします。上記ドキュメントの「APIキーを設定する」に従い、APIキーを取得できます。

開発

(コード全文は記事下部にあります)

お試し

とりあえず一回実行してみます。一回実行するだけならコマンドラインでも可能ですが、後に書き加えるのでシェルスクリプトにします。今回は仮に test-psi.sh とします

#!/bin/bash
set -e

TEST_URL=https://techlab.q-co.jp
curl https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=$TEST_URL

分析結果の数値や改善点の項目が並んだ巨大なJSONデータが返ってきます。

出力の整形

計測の目的にもよりますが、そのままのデータは巨大すぎるので必要な項目をピックアップします。
今回は、単純なパフォーマンス指標として Lab Data の CLS, LCP, SI (Speed Index) を対象にします。(Web Vitals としたいところですが、FIDはLab Dataにはありません)

jq を使って必要な値を抽出します。計測結果を複数回参照することになるので、計測結果を一旦ファイルに書き出します。

API_KEY=<GoogleのAPI KEY>
TEST_URL=https://techlab.q-co.jp
DATE=$(date +'%Y%m%d-%H%M%S')

DATA_FILE="psi-data-$DATE.txt"
curl -o $DATA_FILE https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=$TEST_URL

CLS=$(cat $DATA_FILE | jq '.lighthouseResult.audits["cumulative-layout-shift"].displayValue' | tr -d '"')
LCP=$(cat $DATA_FILE | jq '.lighthouseResult.audits["largest-contentful-paint"].displayValue' | tr -d '"')
SI=$(cat $DATA_FILE | jq '.lighthouseResult.audits["speed-index"].displayValue' | tr -d '"')

cat << EOF

  Lab Data

  Cumulative Layout Shift                    | ${CLS}
  Largest Contentful Paint                   | ${LCP}
  Speed Index                                | ${SI}
EOF

返却されたデータには displayValue(sなど単位が付いている)でなく numericValue もありますが、結果が1以下の少数の時に浮動小数点表記となってしまうため、displayValueの方を使います。

ループ

複数回の結果を出したいので上記コードをループで回します。test-psi.sh 10 のようにコマンド時に回数を受け取るようにします。
冒頭に引数をチェックする処理を付けます。

TEST_COUNT=$1
REGEX='^[0-9]+$'

if ! [[ $TEST_COUNT =~ $REGEX ]]; then
  echo "Please provide a number"
  exit
fi

「出力の整形」時点のコードを関数にし、その下でループを実行します。
一時ファイルを消すための cleanup もついでに定義します。

function run_psi() {
  local DATA_FILE="psi-data-$DATE-$i.txt"
  curl -v -o $DATA_FILE  https://www.googleapis.com/pagespeedonline/v5/runPagespeed?key=$API_KEY\&url\=$TEST_URL\?attempt=$i

  local CLS=$(cat $DATA_FILE | jq '.lighthouseResult.audits["cumulative-layout-shift"].displayValue' | tr -d '"')
...

}

function cleanup() {
  echo -e "\nCleaning up...."
  rm psi-*.txt
}

## Main
for i in $(seq 1 $TEST_COUNT); do
  run_psi $i
done

cleanup

関数内の変数はそれぞれ local と付けておきます。

単に連続で実行すると同じURLに対しては一定時間の間同じ結果が返ってきてしまいますので、ダミーのクエリーストリング attempt=回数 を付けて回避しています。

貼り付け用の結果の表示

スプレッドシートに貼り付ける用の結果が出てくれると、その先で平均値や中央値を取るなどに使えて便利なので、そのためのタブ区切りデータを出力します。RESULT_FILE にループごとにタブ区切りの結果を蓄積していき、最後に出力します。

RESULT_FILE="psi-result-$DATE.txt"

touch $RESULT_FILE

function run_psi() {

...

  echo -e "${LCP%[[:blank:]]s}\t${CLS}\t${SI%[[:blank:]]s}\t" >> $RESULT_FILE
}

...

done

echo -e "\n"
echo -e "LCP(Lab)\tCLS(Lab)\tSI(Lab)"
cat $RESULT_FILE

cleanup

コード全文

クリックして展開
#!/bin/bash
set -e

TEST_COUNT=$1
REGEX='^[0-9]+$'

if ! [[ $TEST_COUNT =~ $REGEX ]]; then
  echo "Please provide a number"
  exit
fi

API_KEY=AIzaSyCWaS_ugfkmVSD6WHr7o-Tz_mKCubeKPfI
TEST_URL=https://techlab.q-co.jp
DATE=$(date +'%Y%m%d-%H%M%S')
RESULT_FILE="psi-result-$DATE.txt"

touch $RESULT_FILE

function run_psi() {
  local DATA_FILE="psi-data-$DATE-$i.txt"
  curl -o $DATA_FILE  https://www.googleapis.com/pagespeedonline/v5/runPagespeed?key=$API_KEY\&url\=$TEST_URL\?attempt=$i > /dev/null 2>&1

  local CLS=$(cat $DATA_FILE | jq '.lighthouseResult.audits["cumulative-layout-shift"].displayValue' | tr -d '"')
  local LCP=$(cat $DATA_FILE | jq '.lighthouseResult.audits["largest-contentful-paint"].displayValue' | tr -d '"')
  local SI=$(cat $DATA_FILE | jq '.lighthouseResult.audits["speed-index"].displayValue' | tr -d '"')

  cat <<EOF

  Lab Data

  Cumulative Layout Shift                    | ${CLS}
  Largest Contentful Paint                   | ${LCP}
  Speed Index                                | ${SI}
EOF

  echo -e "${LCP%[[:blank:]]s}\t${CLS}\t${SI%[[:blank:]]s}\t" >> $RESULT_FILE
}

function cleanup() {
  echo -e "\nCleaning up...."
  rm psi-*.txt
}

## Main
for i in $(seq 1 $TEST_COUNT); do
  run_psi $i
done

echo -e "\n"
echo -e "LCP(Lab)\tCLS(Lab)\tSI(Lab)"
cat $RESULT_FILE

cleanup


確認

このようなログが得られれば完了です。
スプレッドシートへの貼り付けも確認してみてください。

Share

JestでspyOn関数を使って、windowをモックする方法next/image でパフォーマンスが改善されなかった話