メルカリShopsフロントエンドのパフォーマンスを可視化する

はじめに

こんにちは!ソウゾウのSoftware engineerの@yosanです。
メルカリShops [フライング] アドベントカレンダー2022」5日目を担当します。

今回はメルカリShopsで行っている、フロントエンドのパフォーマンスの可視化について説明したいと思います。

メルカリShopsにおけるフロントエンドのパフォーマンス可視化

メルカリShopsはWebベースのアプリケーションであり、大まかに次のような構成で運用されています。

iOSやAndroidのネイティブアプリケーションに中おいても、メルカリShopsの部分はWebViewによって提供されています。

この記事における「フロントエンドのパフォーマンス」とは、いわゆるWeb Vitalsになります。例えば、ユーザがサイトにアクセスしてからコンテンツが表示されるまでに何秒かかっているか、あるいは意図せず画面レイアウトがガタガタ動いてしまっていないか、といったユーザ体験に関する数値になります。
現在メルカリShopsではこのWeb Vitalsを、下のようなダッシュボードを使って可視化しています。これを用いてWeb Vitalsの数値が低いページを探索したり、毎朝Slackに通知して変化を監視したりしています。

Web Vitalsの計測方法

Web Vitalsを計測するには大きく分けて2つの方法があると思います。

  • クライアントサイドから数値を送信する。
  • 外から対象サービスにリクエストを送信して計測する。

クライアントサイドから送信する場合、フロントエンド側にWeb Vitalsを送信する実装を追加する必要があります。例えばFirebase Performance MonitoringSentryを使った方法では、フロントエンドのbundleにSDK同梱することで、SDKが自動的にパラメータを収集し、計測サービス側で可視化されます。

この方法では、ログインが必要なページも含めた、実際のユーザがアクセスしている全ページのデータが収集可能です。また、ユーザのネットワーク状況も加味されたリアルなデータが取得できます。

その反面、Next.jsのbundleサイズの増加に注意を払う必要があります。例えばFirebaseでの計測を行う場合はFirebase SDKをbundleに含める必要がありますが、その分bundleサイズが増加してしまい、結果表示までの時間が悪化する可能性があります。またDynamic Importを使用する場合、最初にダウンロードされるchunkに含まれないので、正確なWeb Vitalsが計測できるか分かりません。

外部から対象サービスにリクエストを送信して計測する場合は、フロントエンドにWeb Vitals送信用の実装を行う必要はなく、bundleサイズ増加の懸念もありません。例えばCalibreSpeedCurveを使用すれば、外部サーバが対象サービスにリクエストを送ってデータを収集できます。計測時のページのスクリーンショットが確認できたりするのもメリットです。

一方で、計測対象のURLを指定する必要があり、そのWeb Vitalsは指定されたページのもののみになります。例えば商品ページに対して、特定の条件に適合する商品ページでだけWeb Vitalsが悪化した場合、それに気づけないかもしれません。また、出店者向けのページについて計測したい場合は計測用のページを作成する必要があり、リアルな数値を得ることができません。

メルカリShopsでの計測方法

メルカリShopsではNext.jsのパフォーマンス計測機能を使ってWeb Vitalsを収集しています。これはクライアントサイドから数値を送信する方法に該当します。Next.jsに搭載されている機能なので、bundleサイズ増加の懸念は不要です。また、Next.js特有のCustom Metricsも収集できるのが特徴です。例えばSSRページへの遷移の際に発生する、サーバレスポンス待ちの時間も計測できます。

Next.jsが提供してくれているのは計測結果の提供のみなので、この数値を送信するための実装や、可視化の仕組みの構築が必要になります。メルカリShopsではユーザの行動ログをGoogle Analyticsで計測しており、パフォーマンス計測にもこれを流用することで、パフォーマンス計測のためのオーバーヘッドは最小限にできています。

全体の構成としては次の図のようになっています。

Next.jsからレポートされるWeb Vitalsの値がGoogle Analytisに送信されます。Google AnalyticsはBigQueryとデータをSyncしており、特定のdatasetからrawデータを取得できます。この結果をLooker Studioで集計し、グラフとして可視化します。

BigQueryで集計できるようにするまでの設定

まずはNext.jsからWeb Vitalsを送信する実装を行います。

Next.jsの公式ドキュメントにGoogle Analyticsの例が掲載されています。メルカリShopsではGoogle Tag Managerを使用しての送信になりますが、ほぼ同じ実装を行っています。

Google Tag Managerを利用する場合は、Google Analyticsに値を送信する設定が必要です。

Google AnalyticsではBigQuery Linkingを有効にしておきます。Streaming Exportも使用しないと直近の数値の変化に気づけないので、コストの問題がなければ有効にすることをおすすめします。

これで準備完了です。

Looker Studioによる可視化

Looker Studioを使うとBigQueryを使った集計結果を簡単に可視化することができます。

現状Web Vitalsについては監視したいものに対してパーセンタイル値を表示するようにしています。特にCore Web Vitalsに関しては目安の指標があるので、収集されたデータを「Good」「Needs Improvement」「Poor」に分類し、その割合を表示するようにしました。

今回の構成の問題点として、Google Analyticsと同期しているテーブルには他の大量のデータも一緒に存在するため、そのままだとクエリに時間がかかる点があります。Looker Studioを探索的に使用したい場合に不便です。中間テーブルを作成するか、Table Samplingを利用するなどしてクエリを軽量化する必要があります。

今回の可視化の目的の1つはパフォーマンスに問題のあるページを発見することなので、URLやデバイスの種類を選択することで、パフォーマンスの悪いページを探索できるようにしました。

Slack連携

ダッシュボードを作ったものの開発メンバーが自発的に見に行くのは難しいので、定期メール通知の機能とSlackのメールインテグレーション機能を組み合わせて、Slack上に定期的に通知するようにしています。

残念ながらメール内容はデフォルトで折りたたまれてしまっているので、確認にワンアクション必要です。調べてみたのですが、Google App ScriptやZappierなどを使ってGmailと連携する方法しか見つからず、メンテナンス性を考え今回はこの構成のままとしました。

今後はLookerのSlack連携機能を使って通知するようにしたいと思っています。

利用状況について

今回のダッシュボードを利用して、パフォーマンスを改善すべきページについて議論したり、数値の変化に気づいて原因を確認したりしています。

改善すべきページは、アクセス数の多いページやSEO的に重要なページの中でWeb Vitalsの数値が悪いものになります。数値が悪い要因はこの可視化の結果だけではわからないので、Cloud Runのlatencyの集計や、ブラウザのDeveloper Toolsによる調査などを行い、対策案を検討します。行った対策に対して改善効果が数値で確認できるのも、可視化のメリットです。

おわりに

今回の記事ではメルカリShopsのパフォーマンス可視化について、その仕組みとメリットについても紹介しました。この次の記事「メルカリShops パフォーマンス改善 奮闘記」では、実際に行った改善内容についてご紹介いたしますので、ぜひそちらもご覧ください。

株式会社ソウゾウではメンバーを大募集中です。メルカリShopsの開発やソウゾウに興味を持った方がいればぜひご応募お待ちしています。詳しくは以下のページをご覧ください。
Software Engineer
Software Engineer, Site Reliability
Software Engineer (Internship) – Mercari Group (※新卒採用に応募するにはまずインターンへの参加をお願いしています。)
またカジュアルに話だけ聞いてみたい、といった方も大歓迎です。こちら の申し込みフォームよりぜひご連絡ください!

  • X
  • Facebook
  • linkedin
  • このエントリーをはてなブックマークに追加