こんにちは、GMOアドマーケティングで主にめるもとGMOSSPのフロント周りを開発しているY.A.です。
本記事では媒体の運営者目線で、Core Web Vitals(以降、CWV)対策の効果測定のために、指標をグラフ化した簡易レポート画面を、「PageSpeed Insights 」(以降、PSI)、「Google Apps Script」(以降、GAS)、そして「Google データポータル」(以降、GDP)を使って作ってみます。
完成イメージは次のようなものです。
非常にシンプルなものなので、GASやGDPの使用経験ある方であれば比較的すぐに構築できるかと思います。エンジニアに限らず、上記経験ある方良ければお試しください。
※なお記事内の画像は筆者のデスクトップからキャプチャを取ったものであり、以降掲載しているUI画面は、2021/05/25時点のものです。その後変更あるかもしれないのであらかじめご了承ください。
背景
昨年からCWVが話題になっています。
そもそも検索ランキングにどれくらいの影響があるかですが、直近Q&Aを見る限り、まず「関連性の高い優れたコンテンツであることが重要」であり、CWV含むページエクスペリエンスはその次、とされているようです。
ランキングでは、ページ エクスペリエンスに該当する要素が平均以下であっても、総合的に優れた情報を含むページが引き続き優先されます。ページ エクスペリエンスが良好でも、関連性の高い優れたコンテンツに勝ることはありません。
しかし「優れたコンテンツ」がどのように測られているのかよくわからない以上、「ページエクスペリエンス」が指標化・定量化され、競うポイントが明確になったCWVに注目が集まってしまうのは無理のないことです。
なおCWVは、具体的には同じ品質の記事があるときに「tie breaker」として利用されるとのことです。
これは、過去に行ったモバイル フレンドリー アップデートや Speed Update などの変更に似ています。これらのシグナルと同様に、ページ エクスペリエンスは「タイブレーク」の状況では重要になります。同様の品質とコンテンツを含むページが複数ある場合、ページ エクスペリエンスが優れているページは、そうでないページよりもパフォーマンスが高くなる可能性があります。
端的に言えば、まだ改善に取り組んでいる最中というサイト運営者の方も、Google がページ エクスペリエンスの使用を開始した時点ですぐに大幅なランキングの低下が発生すると心配する必要はありません。しかし、今後については、ページ エクスペリエンスの改善を優先事項にするべきです。なぜなら、これからページ エクスペリエンスを改善していくサイトがますます増えれば、サイト運営において軽視できない規準になるからです。
競合がCWV対策を講じることでページエクスペリエンスの差が広がっていくため、日を経るごとにその重要性は高まりそうです。結局CWVも大事は大事ということですね。
さて前置きが長くなりましたが、各種CWV改善施策を打っていく上で、それらがどの程度スコア改善に寄与したかを確認するためには、継続的に数値を追えるツールは必須です。
CWVの計測ツールについてはさまざまなところで紹介されていますが、有料のサービスならまだしも、無料ツールとなるとどうしても帯に短し襷に長しと感じる方も多いのではないでしょうか。
弊社の「めるも」においても、エンジニアサイド・ビジネスサイド両方にわかりやすいものを探していたのですが、結局のところ、次の要件を満たせば最低限レポートツールとして使えることがわかりました。
1) PSIで出力されるCWVのフィールドデータ/ラボデータのスコアを定期的に取得・保存
2) 1.を時系列でグラフ化
実現にはPSIのAPI、GAS、GDPを利用しました。
以下、具体的に簡易レポート画面構築までの必要な3ステップを解説していきます。
目次
【Step1】 PSIのAPIキーの取得
まずはPSIで利用するAPIキーを取得します。
取得方法は、下記ページの「キーを取得する」をクリックします。そこでプロジェクトを選択して作成します。
https://developers.google.com/speed/docs/insights/v5/get-started?hl=ja
あるいはそのまま認証情報ページにて作成することも可能です。
https://console.developers.google.com/apis/credentials?hl=ja
【Step2】 GASの用意とトリガーの設定
次に、APIキーでPSIのデータを取得して、Google スプレッドシート (以降、スプレッドシート)のシートに入れていくGASのscriptを作ります。
まずはデータを保存するためのスプレッドシートを用意します。
名前は適当で問題ありませんが、あとでGDPでデータ参照しますので、わかりやすい名前が良いと思います。シートも同じくあとで参照しますのでわかりやすい名前が良いです。
次に、メニューにある「ツール」 > 「スクリプト エディタ」からGASのエディタ画面を開きます。
画面を開いたら、次のコードを設定します。
GASに設定するコード
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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
// 取得したAPIキーを設定 const API_KEY = 'xxxxxxxxxxxxxxxxx'; function recordPSIHourly() { const ss = SpreadsheetApp.getActiveSpreadsheet(); // 計測したいページURL情報とそのデータ格納場所のシートを設定 const sheet = ss.getSheetByName('_example'); exec(sheet); } function exec(sheet) { // 取得するURL const url = 'https://news.merumo.ne.jp/genre/010/1'; const request = setUpQuery(url); let response = [] try { response = [ UrlFetchApp.fetch(request, { muteHttpExceptions: true }) ]; } catch (err) { Logger.log(err); return err; } // データを入れるための行を挿入 sheet.insertRowBefore(2); // 1列目にログの日付 const date = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd HH:mm'); sheet .getRange(2, 1) .setValue(date); const parsedResult = JSON.parse(response[0].getContentText()); const mobileResult = convertResult(parsedResult); // 2列名以降に取得データの出力 sheet .getRange(2, 2, 1, mobileResult[0].length) .setValues(mobileResult); } // 取得データの変換 function convertResult(content) { const arr = [ [] ]; // lighthouseMetrics(ラボデータ) const audits = content.lighthouseResult.audits; arr[0].push(sanitizeUnit(audits['first-contentful-paint'].displayValue)); arr[0].push(sanitizeUnit(audits['interactive'].displayValue)); arr[0].push(sanitizeUnit(audits['speed-index'].displayValue)); arr[0].push(sanitizeUnit(audits['total-blocking-time'].displayValue)); arr[0].push(sanitizeUnit(audits['largest-contentful-paint'].displayValue)); arr[0].push(sanitizeUnit(audits['cumulative-layout-shift'].displayValue)); // cruxMetrics(フィールドデータ) const metrics = content.loadingExperience.metrics; arr[0].push(metrics.FIRST_CONTENTFUL_PAINT_MS.percentile / 1000); arr[0].push(metrics.FIRST_INPUT_DELAY_MS.percentile); arr[0].push(metrics.LARGEST_CONTENTFUL_PAINT_MS.percentile / 1000); arr[0].push(metrics.CUMULATIVE_LAYOUT_SHIFT_SCORE.percentile / 100); return arr; } // ms, sなどの単位について除去 function sanitizeUnit(str) { const num = str.replace(/\s?[ms|s]/g, ''); return num; } // クエリー作成 function setUpQuery(url) { const api = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed'; const parameters = { url: encodeURIComponent(url), key: API_KEY, strategy: 'mobile', // モバイルのみ取得 }; let query = api + '?'; for (key in parameters) { query += '&' + key + '=' + parameters[key]; } return query; } |
- 「xxxxxxxxxxxxxxxxx」 の部分には取得したAPIキーをセットしてください。コードをセットしたら保存(Ctrl + s)
const url = 'https://news.merumo.ne.jp/genre/010/1'
の箇所に実際に取得したいURLをセットしてください
なおPSIでは様々な指標を取れます。上のscriptではPSIのwebページで「分析」を掛けた際に掲載される代表的な数値を取得していますが、必要に応じて変更ください。
API Reference
https://developers.google.com/speed/docs/insights/rest/v5/pagespeedapi/runpagespeed
最後に、メニューにて関数で「recordPSIHourly」を選択し、「実行」ボタンをクリックします。先のスプレッドシートのシートにデータが書き出されたら成功です。
なお完了までには少し時間がかかります。
また初回はスプレッドシートとの連携で承認を求められますので、承認しましょう。
成功すると次のようになります。
トリガーの設定
自動的に定期実行したいので、GASのトリガーを設定します。
左側のメニューからトリガーを選択しましょう。
フィールドデータの更新頻度は1日1回のため、もしフィールドデータだけ取得するならば1日に1回、ラボデータならせいぜい1時間に1回でよいでしょう。
ここではとりあえず1時間に1回実行しています。
これで1時間ごとに自動実行され、スプレッドシートにデータが溜まっていくはずです。
この後、GDPにこれらデータを取り込んでいくのですが、その際にフィールド名を取得するため、1行目にそれぞれの指標名を入れておきましょう。
【Step3】 GDPでグラフ描画
Step2がうまくいったら、それをGDPで読み込みます。
GDPで作成 > データソースを選択します。
次に追加するデータで、「Google スプレッドシート」を選択します。
該当スプレッドシートを選択し、「接続」をクリックします。
なお複数ワークシートがある場合、シートごとに追加する必要があるので表示させたいデータ分だけ、シートの追加作業を繰り返し行ってください。
以下の内容で問題なければ「レポートを作成」をクリックします。
「レポートに追加」または「キャンセル」をクリックしてください。
「レポートに追加」を選択した場合次のグラフになりますが、時系列グラフが良いので、出力されたグラフを削除します。
メニューの「グラフを追加」から、例えば「時系列グラフ」を追加します。
表示させる指標を選択します。デフォルトで設定されている「Record Count」をクリックし試しに「cummulative layout shift」を選択します。
次に集計方法を変更します。デフォルトだと「合計」のため、「中央値」に変更します。
なお「中央値」にする理由は、ページ内で展開されるそのときどきの3rd Partyリソース(広告など)により極端なばらつきが発生することも多いため、「平均値」よりは「中央値」で見た方がより実態に近いものを見れるためです。
まだ1日分しかないのでわかりやすいグラフになっていませんが、トリガーが問題なく動けばこれで日毎の推移を追うことができます。
また各指標ごとに時系列グラフを作ることで次のようにできます。
以下、その他の指標、CWVの基準値追加、テーマ、デザインを変更したものです。
例)CWVの3指標だけをまとめたグラフ。小文字はラボデータ、大文字はフィールドデータ 。
※フィールドデータは途中から計測し始めたため、グラフ上、途中から表示されています。
例)PSIに出てくる指標を全て表示したグラフ
まとめ
以上PSIとGASとGDPを使って作る簡易レポート画面の説明でした。
紹介したのは必要最低限のやり方ですので、それぞれの状況に合わせて取得するページや、指標など細かくチューニングしてみてください。
なお簡易ではあるものの、レポート画面が実際あると無いとで、サイト分析に大きな差を生むかと思います。
例えば、CWV対策を始めるとCLSについてはなかなか改善できないケースがあるかと思います。具体的にはラボデータ上では改善しているのに、フィールドデータではなかなか改善が見受けられない場合などですね。
原因の一つとして考えられるのは、「CLSのラボデータはあくまでページがloadされるまで、フィールドデータはユーザーがページをunload(離脱)するまで計測される」という違いです。
CLS measures the sum total of all individual layout shift scores for every unexpected layout shift that occurs during the entire lifespan of the page.
Caution: Lab tools typically load pages in a synthetic environment and are thus only able to measure layout shifts that occur during page load. As a result, CLS values reported by lab tools for a given page may be less than what real users experience in the field.
つまりユーザーがスクロールして行って、そのスクロール中にビューポート内でレイアウトシフトが起きている場合、それもカウントされているということです。
ちなみにCLSは最近再定義され、「Session Window」という概念で計算されるようになりました。詳しくは下記記事を参考ください。
https://www.suzukikenichi.com/blog/google-updates-definition-of-cumulative-layout-shift/
この点気づかずにPSIの指摘事項≒ファーストビュー(Above the fold)でのレイアウトシフトのみ最適化していると、フィールドデータのスコアはなかなか改善しません。
ただPSIだけ見ていると気付きにくい点ですが、このような特徴も、時系列グラフの簡易レポート画面を見ていたおかげでわかりました。
もし用意して無ければ、CLSの改善にもっと時間がかかったかもしれません。(もちろん最初からちゃんとドキュメント読め、という話でもありますが!)
なおそれ以外にもCWV対策やってみると上記CLS以外でも様々な注意ポイントが分かりました。
それらはまた別の機会に共有したいと思いますが、とにかく困ったら公式ドキュメントを読むのがお勧めです。
多くは英語ドキュメントのみですが、ほとんどの疑問は解決できると思っています。少なくとも下記は目を通しておくと良いでしょう。
https://web.dev/lcp/
https://web.dev/fid/
https://web.dev/cls/
少し脱線しましたが、以上です。
一緒にページエクスペリエンスを向上させていきましょう!