こんにちは!会員システムグループの渡邊です。普段はニフティトップページの運用を担当しています。
今回はGoogle Apps Script(GAS)を使い、コストをかけずにサイト表示速度の見える化を行う方法を紹介します。
なぜ見える化を行おうと思ったか
Googleが2020年にWebサイトのパフォーマンスを評価するための指標であるCore Web Vitals(CWV)を導入しました。
この指標には、Webサイトのパフォーマンス改善に非常に役立つ内容が含まれています。
CWVの指標はUX改善に直結するため、担当サービスではCWVを軸に改善活動を行っています。
しかし、改善活動を行っていく中でリリースによる影響やGoogleのアルゴリズム変更によってスコアが変動することが増えてきたので、継続的な見える化を行う必要が出てきました。
表示速度見える化の検討
初めはLightHouse CIを使って見える化を検討していましたが、いくつかの懸念点があり断念しました。
- LightHouse CIは実行するサーバー環境によってスコアが左右されてしまうため、安定した計測を行うには高いサーバースペックが求められるため、コストがかかってしまう
- またLightHouse CIはサーバーなどに置いて管理することが必要になるので運用コストが増える
以上のことから最終的には以下のツールを使って作成することにしました。
- PageSpeedInsights API
- Google スプレッドシート
- Google Apps Script(GAS)
今回利用したGCPが提供しているPageSpeed Insights APIは、リクエストに制限はありますがコストはかからずに利用できます。現在、1時間おきに実行していますが、特に問題は起きていません。
APIキーを使わなくてもPageSpeed Insights APIは実行できますが、すぐに上限に引っかかってしまうため、今回はAPIキーを発行して計測を行っています。
構成とデータ取得スクリプト
構成図
データ取得(GAS)
まずAPIキーを取得します。PageSpeed Insights API を使ってみるにアクセスし、「キーを取得する」ボタンを押すとモーダルが開くのでGCPのプロジェクトを選択します。
次にAPIキーが発行されたらGASのスクリプトプロパティにAPIキーを設定します。
GASのスクリプトは以下のようになっていて、処理を簡単に説明するとPageSpeed Insights APIのレスポンスからCWVの指標を一つ一つ変数に格納し、指定したシートの末尾に追記していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
function myFunction() { // 対象のスプレッドシートを取得 const ss = SpreadsheetApp.getActiveSpreadsheet(); // 書き込むシートを指定 const sheet = ss.getSheetByName("結果"); writeResult(sheet, getResult()); } function getResult() { // APIキーを取得 const key = PropertiesService.getScriptProperties().getProperty('PSI_API_KEY'); // URLを指定 const url = "https://www.example.com/" // PageSpeed Insights APIを実行 const result = UrlFetchApp.fetch( 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed' + `?url=${url}` + "&locale=ja" + "&strategy=desktop" + `&key=${key}` ); return JSON.parse(result); } function writeResult(sheet, arr) { // 実行日時取得 const date = new Date(); const ExecDate = date.getFullYear() + '/' + (date.getMonth() + 1) + '/' + date.getDate() + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds(); // パフォーマンススコア取得 const performance = arr["lighthouseResult"]["categories"]["performance"]; // First Cotentful Paint取得 const fcp = arr["lighthouseResult"]["audits"]["first-contentful-paint"]; // Time to Interactive取得 const tti = arr["lighthouseResult"]["audits"]["interactive"]; // Speed Index取得 const si = arr["lighthouseResult"]["audits"]["speed-index"]; // Total Blocking Time取得 const tbt = arr["lighthouseResult"]["audits"]["total-blocking-time"]; // Largest Contentful Paint取得 const lcp = arr["lighthouseResult"]["audits"]["largest-contentful-paint"]; // Cumulative Layout Shift取得 const cls = arr["lighthouseResult"]["audits"]["cumulative-layout-shift"]; // シートに追加 sheet.appendRow([ ExecDate, performance["score"] * 100 + "%", parseFloat(fcp["displayValue"]), parseFloat(tti["displayValue"]), parseFloat(si["displayValue"]), parseFloat(tbt["displayValue"]), parseFloat(lcp["displayValue"]), cls["displayValue"] ]); } |
また、1時間おきに実行するためにトリガーを以下のように設定しています。
結果
スプレッドシートへの出力結果
出力結果をもとにグラフ化
過去のリリースやアルゴリズム変更の影響を確認したかったので、期間を自由に変更できるタイムライングラフを使っています。
終わりに
今回はコストをかけずにサイト表示速度の見える化を行いました。
グラフ化や平均値などは手動で作らなければいけませんでしたが、一度作ってしまえばAPIがダウンしない限り永久的に結果を更新し続けてくれるので非常に便利になりました。
担当プロダクトではGitHubリリースノートの自動生成も行っているので、今回作成したものと突き合わせることでどのリリースが原因かの特定が容易になりました。
将来的には週の始まりにグラフを画像化したものをSlack通知する仕組みを導入する予定です。