ドクターズプライム Official Blog

「救急車たらい回しをゼロにする」ドクターズプライムの公式ブログです

ドクターズプライムOfficial Blog

Web パフォーマンスとプロダクト KPI の相関を可視化する話 2022ver

@1000ch (id:hc0001) です。技術顧問業としては広報周りの戦略を考えていることが多いのですが、今日はエンジニアリングの話です。

ドクターズプライムのプロダクト開発の中でも、パフォーマンス上の課題を発見して改善に取り組むことがあります。今回は @oinume (id:oinume) さんから 「この辺りの実装が問題になっていそう…」 という相談があったので、私がアプリケーション全体を眺めてボトルネックになっている箇所をいくつかピックアップし修正方針を提案したのですが、 実装を修正する前に 「まずは継続的にモニタリングできる環境を準備してパフォーマンスの前後がわかるようにしましょう」 ということで原点回帰した話です。

Core Web Vitals でリアルユーザーモニタリング

つまり、WebパフォーマンスとプロダクトKPIの相関を可視化する話 をドクターズプライムでもやりましょうという話です。もう 5 年近く前ということにドン引きしていますが、2022 年でもやっていきます。

developers.cyberagent.co.jp

パフォーマンス指標とプロダクト KPI の選定

当時は Speed Index をメインの指標として使っていて、First Contentful Paint の策定が進んでいる…といった状況だったようですが、最近では更に成熟したパフォーマンス指標として Core Web Vitals が定着しているので、LCPFIDCLS の3つを使っていきます。LCP は First Paint や First Contentful Paint1 の後継の指標ですね。

web.dev

パフォーマンス指標との相関を見るプロダクト KPI(ユーザー体験の指標)については、GA4 の標準で計測できる指標(エンゲージメント等)を使うのがイメージを掴むにはてっとり早いと思います。もちろん、既に設定されているプロダクトの重要指標があれば、そちらを参照する方が「エンジニアリングのリソースを割くべきか?」といった場面でより合理的な判断を導けると思いますが、今回は パフォーマンス指標とプロダクト KPI の相関を可視化する ことをゴールに話を単純化するために、他 KPI の話を省きます。

リアルユーザーモニタリングと合成モニタリング

リアルユーザーモニタリングは、実際にユーザーが実際にアプリケーションを使っている際の性能を計測する手法です。そのため、実際のユーザー環境でのパフォーマンスが、ユーザー体験にどう影響するのかを検出できます2。一方で合成モニタリングは、ネットワーク環境やマシンの性能、ブラウザ等を固定し変数を取り除いて計測することで、ソフトウェアのボトルネックを検出するのに適しています。

合成モニタリングもやりたいところですが、既に Google Analytics を使って各種指標を計測していたことや、タイムリーに GA4 の勉強をしていたデータアナリストがいたなどの状況が相まって、今回は Core Web Vitals を指標としたリアルユーザーモニタリングをすることから始めました。

データの収集と可視化

収集するパフォーマンス指標とプロダクト KPI を決めたところで、実際にデータを集めていきます。

Core Web Vitals の計測データを Google Analytics に送信する

まずはユーザー環境で実行されるアプリケーションの性能を計測します。Core Web Vitals の計測には Google Chrome チームが提供している GoogleChrome/web-vitals があるので、こちらを使います。CDN でも提供されているので、今回は CDN から直接ロードしています。

次に、ライブラリを遣って計測したデータを Google Analytics に送信するので、README で例示されているように gtag() 関数を使います。当然ながら、gtag() を実行する前に GA4 のスクリプトがロードされている必要があります。

import {getCLS, getFID, getLCP} from 'https://unpkg.com/web-vitals@2.1.2/dist/web-vitals.js';

function sendCoreWebVitalsData({name, value, delta, id}) {
  gtag('event', name, {
    value: Math.round(name === 'CLS' ? delta * 1000 : delta),
    metric_id: id,
    metric_value: value,
    metric_delta: delta,
  });
}

getCLS(sendCoreWebVitalsData);
getFID(sendCoreWebVitalsData);
getLCP(sendCoreWebVitalsData);

これだけでデータを集めるという目的は達成できるので、非常に簡単です。

Google Analytics でデータを集計するメリットとして、ユーザーのセッション管理やセッションに紐づくユーザー体験の指標、そして任意の送信データを、GA4 の標準機能として管理できる点にあると思います。つまり計測されたレコードに、パフォーマンス指標のスコアとユーザー体験の指標(ここではエンゲージメント)が紐付いてくれます。

Google Analytics のデータを BigQuery にエクスポートする

最終的な可視化手段は Spreadsheet や Data Studio などの選択肢がありそうですが、いずれもデータソースを GA4 にできそうです。今回は、データ分析基盤として既に BigQuery を採用していたので、GA4 に集積されたパフォーマンスの計測データも BigQuery にエクスポートすることにしました。GA4 から BigQuery へのエクスポートもサポートされているので、特に詰まる点はなく連携できるのではないでしょうか。

BigQuery のデータを Data Studio で可視化する

結論から言うと、次のようなグラフを @anboorin さんが作ってくれました。話の趣旨と意図を正確に理解して、一瞬で作ってくれるデータアナリストの存在は偉大です。

f:id:hc0001:20220209224150p:plain
BigQuery に集計された RUM の計測データを Data Studio で可視化したグラフ

手順としては以下の通りです。

  1. Data Studio 用のデータソースを BigQuery で作成する
    1. event_datepage_path を追加する
    2. LCP, FID, CLS などのパフォーマンス指標を追加する
    3. engaged などのプロダクト KPI を追加する
  2. Data Studio でレポートを作成する
    1. データソースに BigQuery を選択する
    2. プロジェクト > データセット から、作成した BigQuery のテーブル(表)を追加する
  3. Data Studio でグラフを作成する
    1. グラフを追加 > 平滑線グラフ から、グラフを追加する
    2. グラフをクリックし、右ペインから ディメンション としてパフォーマンス指標を追加する(例: LCP や CLS や FID など)。Web Vitals の計測結果を加工せずに送信している場合、 フィールドを作成 から「ROUND(LCP / 100, 0) * 100」のように値を丸めて集計したほうが綺麗に成形できる
    3. グラフをクリックし、右ペインから 指標 としてプロダクト KPI を追加する(例: GA4 標準の engaged など)。 フィールドの作成 から「SUM(engaged) / Record Count」として、レコードあたりの値に成形する
    4. グラフをクリックし、右ペインから フィルタ を追加して、パフォーマンス指標のデータの外れ値を除外する。任意のフィルタ名を入力し、 除外条件 として除外したいパフォーマンス指標(例: LCP や CLS や FID など)を選択し、 null である を選択する
    5. コントロールを追加 > 期間設定 から、データの期間を指定するコントロールを追加する
    6. コントロールを追加 > プルダウンリスト からコントロールを追加し、 右ペインの コントロールフィールド から page_path を設定する

グラフで可視化されたデータの見方

グラフの見方を少し解説します。3つのグラフが、それぞれ LCP・FID・CLS に対応していることはお分かりかと思います。

f:id:hc0001:20220213154444p:plain
パフォーマンス指標に LCP を、プロダクト KPI にセッションあたりの閲覧ページ数を取るグラフ

棒グラフが各パフォーマンス指標の分布を表しており、横軸をパフォーマンス指標のスコアに、縦軸をユーザー数に取ります。 このグラフではパフォーマンス指標として、ランディング時の LCP を棒形に描画しており、LCP が 1500ms のユーザー数が最も多いことがわかります。パフォーマンスが改善されれば良好なパフォーマンスを体験する人が増えて、棒グラフが左へ(パフォーマンスが良い方へ)推移することが予想できます。

線グラフは横軸をパフォーマンス指標のスコアに、縦軸をプロダクト KPI に取ります。 このグラフではプロダクト KPI として、セッションあたりの閲覧ページ数を線形に描画しています。集計できているデータの母数がまだ少なく統計的な有意差も見難いですが、パフォーマンスが悪いときにプロダクト KPI も悪い兆候も伺えます。これは、データが充分に大きくなることでより綺麗な分布になるでしょう。

こちらのグラフでは期間と URL を指定できるようにしてあります。期間を指定すれば アプリケーションの修正前後でユーザーが体感した、パフォーマンスの変化とプロダクト KPI への影響 を把握できますし、URL を指定すれば どのページのどういった性能に問題があるのか が一目瞭然です。もちろんユースケースに応じて、定点観測する URL をいくつかに絞るなどの応用も出来ます。

おわりに

無事に計測できたところで、ようやく本腰を入れてアプリケーションを改善していけそうです。パフォーマンス改善に関する取り組みについては、続編をお待ち下さい。

こうした品質改善の取り組みに興味がある人、優秀なデータアナリストと働きたい人、ドクターズプライムの事業や組織についてもっと知りたい人向けに、ドクターズプライムの中の人とカジュアルに話したいという記事もありますので、是非お気軽にお声がけください。

blog.drsprime.com

ドクターズプライムのエンジニアリングの現状私から見たフロントエンドの状況についても記事がありますので、よろしければご覧ください。


  1. First Contentful Paint (FCP) は、ページの読み込みが開始されてからページ内のコンテンツのいずれかの部分が画面上にレンダリングされるまでの時間を測定します。

  2. 合成モニタリングとリアルユーザーモニタリングについては超速! Webページ速度改善ガイドでも解説しています