【Sentry】Reactのデバッグを簡単にする方法

初期UIがサーバーでレンダリングされたものと一致しないため、ハイドレーションに失敗したら、とても陰鬱な気持ちになると思います。 Next.jsやReactベースのメタフレームワークを使ってサーバーレンダリングされたページを構築しているなら、ハイドレーションエラーが起きると最悪な気持ちになり、デバッグが困難であることはご存じでしょう。 Reactにおけるハイドレーションとは、サーバー上でHTMLとしてレンダリングされたReactアプリケーションが、ブラウザ上でインタラクティブになるときに発生するプロセスのことです。 ハイドレーションエラーは、クライアント上でReactによってレンダリングされたマークアップが、最初にサーバーからレンダリングされたHTMLと一致しない場合や、サーバーから無効なHTMLが送信され、Reactがそれを修正できなかった場合に発生します。 日付やローカライズなどであれば、避けられないケースとなることも有り得ます。Reactのコードでは、このような不可避な差異に対するエラーを抑制することができますが、ほとんどのハイドレーションエラーは、アプリに何らかのバグがあることを示しています。 この記事では、ハイドレーションエラーの修正方法ではなく、Sentryを使用したハイドレーションエラーをデバッグする方法について説明します。 開発中にハイドレーションエラーが発生すると、選択したJavaScriptフレームワークは通常、エラーを引き起こしたコードに関するいくつかの詳細とともに、大きなエラーメッセージを表示します。 しかし、ハイドレーションエラーは通常、本番環境では表示されませんし、原因も曖昧な状態になりがちです。 一般的なユーザーは、おそらくエラーレポートとともに有用なスクリーンショットを提供することはできないでしょう。 また、ブラウザの開発者ツールなどでエラーを探そうと思うことは皆無に近いでしょう。 さらに言えば、Sentryが自動的に作成するエラー問題も、解決にはあまり役に立たないでしょう。 『セッションリプレイ』を使って原因追及! もしあなたがSentryのセッションリプレイ機能を用いることで、ユーザーがハイドレーションエラーを起こしたときにユーザーセッションの再現を取得する設定なら、Sentryは特定のハイドレーションエラーのイシューを自動的に作成します(しかも無料です!) Sentryが自動的に特定のハイドレーションエラー問題を作成します。 すべての同じエラーをグループ化します。 エラー発生時に存在したサーバーレンダリングと、クライアントレンダリングの両方のマークアップをキャプチャします。 ビジュアルモードと、プレーンHTMLモードの両方で差分を表示します。   注意点として、SentryのJavaScript SDK、バージョン7.87.0以上を使用していることと、セッションリプレイを有効にしていることを確認してください。   グループ化されたハイドレーションエラーが、Sentryでどのように見えるかご紹介します。 Hydration Error(ハイドレーションエラー)という名前なので、課題リストビューで簡単に見つけることができます。 表示するイベント(推奨、最新、最古)を選択し、イベント間を移動してコンテキスト情報を比較できます。 サーバーとクライアントの間でスライドする差分を表示します(差分ビューアを開くと、ビジュアル差分とHTML差分を並べて表示することもできます)。 『ハイドレーションエラーの解決』をクリックすると、ハイドレーションエラーの解決に関するヘルプが表示されます。 ハイドレーションエラーのデバッグ 標準的なハイドレーションエラーの内容は、サーバーでレンダリングされたHTMLがクライアントでレンダリングされたHTMLと一致しなかったと述べていることが多いです。 そのため、差分ビューアーはこれらの違いを見つけるのにとても役立ちます。 Before「ビューはサーバーでレンダリングされたもの」で、 After「ビューはReactがクライアントでレンダリングしたもの」です。 もしかすると、こちらの例でお気づきかもしれません。 それは「変更前」と「変更後」が見た目がほとんど同じに見えるということです。 HTMLの差分を調べると、サーバーでは空白のページがレンダリングされ、クライアントではHTMLがレンダリングされている、というケースがあります。 しかしこれは正しくない状態です。ブラウザのネットワークタブで確認したところ、HTMLは間違いなくサーバーでレンダリングされています。 ハイドレーションエラーの原因となっているコードの本当の問題は、サーバー側でレンダリングされたHTMLと、クライアント・レンダリングされたHTMLが一致していないことではなく、自身が作成したHTMLが無効で(<p>が<p>の中に含まれている)、Reactがエラーを投げたことです。これが『ハイドレーションエラーが最悪な理由』です。 ではなぜdiff(ファイル差分)によると、サーバー上にHTMLがレンダリングされていないように見えるのでしょうか? Reactが無効なHTMLのために無意味なハイドレーションエラーを投げたことを考えると、Sentryは問題が何であるかについて最善の努力を尽くして推測するしかありません。 通常、あるイベントに意味のないdiffがある場合、別のイベントの方が役に立つかもしれません。 要するに、Reactがハイドレーションエラーを投げたときは、修正が必要な問題があるということです。 そして、Reactは本番環境で問題を修正するために必要な詳細を教えてくれないので、Sentryはハイドレーションエラーの差分ツールの空白を可能な限り埋めることで、問題をよりよくデバッグできるようにしてくれます。 ハイドレーションエラーの問題や差分を作成すると、Sentryの利用金額は増える…? すでにセッションリプレイを使用している場合、自動的にグループ化されたハイドレーションエラー課題を『無料』でご利用いただけます。 Sentryのハイドレーションエラー問題は、リプレイとその関連データから生成されるため、エラークォーターにも影響しません。さらに、ハイドレーションエラーのアラートもデフォルトで表示されます。 セッションリプレイを使っているなら、Sentry に送信される前に、デフォルトですべてのテキストコンテンツを「 * 」でマスクし、クライアント上のすべてのメディア要素をブロックすることに気づいたかもしれません。 この記事では、Session Replay SDK がどのように設定されているかによって、ハイドレーションエラーの画像に示されている例は、「 * 」ではなくテキストを表示しています。 […]

【Sentry】Android開発のデバッグを効率化する方法

Androidアプリのデバッグには、クラッシュ、ANR、一貫性のないログなど、独特な課題が豊富にあります。 しかし、問題を素早く特定して解決し、より良いパフォーマンスとユーザー体験を実現する簡単な方法がいくつかあります。 今回は、Android のデバッグを効率化する基本的なツールとテクニックを紹介し、ANR について説明します! Androidデバッグにおける「3つ」の基本 Android StudioのLogcat Logcatはリアルタイムにログを出力し、手動でエラーを見つけるのに役立ちます。このツールでは、以下のようなカスタムタグを使用することで特定の問題を切り分けることが簡単にできます。 Logcatで 「MyAppTag 」でフィルタリングすると、無関係なログを選別することなく、NullPointerExceptionのような特定の問題に焦点を当てることができます。 Android Studioのブレークポイント ブレークポイントは、実行時の動作を検査するために不可欠です。コードの重要な行にブレークポイントを設定します。 ブレークポイントがトリガーされると、Android Studioは実行を一時停止し、変数(結果)を検査したり、コードの実行をステップ実行してロジックの展開を確認したりすることができます。 この方法は、フロー制御や計算の微妙なバグをキャッチするために非常に有効です! ブレークポイントがトリガーされると、Android Studioは実行を一時停止し、変数(結果)を検査したり、コードの実行をステップ実行してロジックの展開を確認したりすることができます。 この方法は、フロー制御や計算の微妙なバグをキャッチするために非常に有効です! Sentry によるリアルタイムのエラー追跡 ローカルでの開発デバッグや手動ログだけに頼るのではなく、Sentry は本番環境でのエラー追跡を自動化します。例えば、APIリクエストが失敗した場合を追跡する場合、以下のように記述します。 Sentryはエラーをキャプチャし、スタックトレース、ブレッドクラム(エラーに至るまでのイベント)、環境の詳細を含む詳細なレポートを生成します。このコンテキストは、アプリが稼動した後に問題を診断し解決するために非常に貴重です。Sentryはまた、スタックトレースやパンくずのような追加コンテキストでLogcatログからエラーレポートをキャプチャし、強化することによって、Logcatと統合することができます。 さて、基本をカバーしたところで、Androidアプリケーションで非常に頻繁かつ一般的な問題であるANRに取り組む方法など、Androidをデバッグするための他の戦略について、さらに深く掘り下げてみましょう。 AndroidでANRを検出する ANR(Application Not Responding)は、アプリのメインスレッドが長時間ブロックされ、システムがエラーダイアログを表示することで発生します。 最も一般的なものは、Input Dispatching Timeoutで、ユーザーが操作した後アプリのメインスレッドが5秒以上応答しない場合に発生します。これはユーザー体験に大きく悪影響を与え、Google Playストアでアプリのダウングレードにつながる可能性があります。 AndroidでANRを検出する方法はいくつかあり、それぞれに長所と短所があります。トレードオフの関係性にあります。以下で確認していきましょう。 ウォッチドッグスレッド: メインスレッドに定期的にタスクを送信します。スレッドが設定した時間(通常は5秒)以内に応答しなかった場合、ANRが発生したと見なされます。この方法はリアルタイムで検出できますが、ユーザーとの対話がない場合は誤検出してしまうリスクがあります。 ネイティブシグナルハンドラ: ネイティブレベルでシグナルハンドラをインストールすることで、システムによって発生したANRをリッスンすることができます。この方法はネイティブのシグナルを捕捉できますが、バックグラウンドのANRをカバーできず、提供されるスレッド情報も限られてしまいます。 アプリケーション終了情報API(Android 11以上): この新しいAndroid APIは、完全なスタックトレース、スレッド情報、デッドロック検出など、ANRの最も正確な検出を提供します。フォアグラウンドANRとバックグラウンドANRを区別しますが、Android 11以上でのみ利用可能です。 ANRの検出方法はまだ半分に過ぎません。 AndroidのANRのデバッグについて、Sentryを使用して説明しましょう。 SentryによるANRのデバッグ ANR が発生すると、Sentry は自動的に発生時のアプリの状態、デバイスのパフォーマンス(メモリやバッテリー容量など)、および完全なスレッドダンプを含む重要な詳細を瞬時にキャプチャします。 実際のシナリオを挙げて、確認していきましょう。 スレッドロッキングの問題でアプリが「Input Dispatching Timeout」を出力したとします。Sentryを使えば、ブロックを引き起こしている正確なスレッドを示す詳細なレポートを受け取ることができます。同期化の問題なのか、何か他のものがメインスレッドをロックしているのかを突き止めることができます。 パフォーマンスプロファイリングを使ってANRを解決する […]

Sentryを使って React のデバッグを改善する方法

このガイドは、一般的なバグやパフォーマンスの問題を特定し、解決する方法を解説していきます。 クライアントサイドのReactのデバッグを扱いますが、サーバーサイドレンダリングを使用するReactアプリを持っている場合は、Node.jsのデバッグガイドやオンデマンドのワークショップの記事でその方法がわかります。ぜひそちらもご覧ください。 以下のセクションでは、次のことを解説していきます。 Chrome DevTools、VS Code、およびReact Developer Toolsを使用したReactデバッグの基礎 最小限のバグと最大限のパフォーマンスを実現するReactアプリを作成する方法 一般的なReactのエラーやパフォーマンス課題を特定する方法、それらの課題を改善する方法 SentryがどのようにしてReactのバグやパフォーマンス課題を本番環境で記録しているか、その問題が発生した際に自ら察知するための方法 Reactデバッグの基礎 Chrome 開発者ツール を使用した React のデバッグ すべての主要なブラウザ開発ツールには、JavaScriptデバッガが含まれています。 ブラウザからF12キーを押すことで、Chrome 開発者ツールのコンソールにアクセスできます。開発者ツールの「Sources」パネルが開き、3つのセクションが表示されます。次の通りです。 ページ コードエディタ デバッガ 「ページ」セクションでは、ページが要求したすべてのファイルのファイルツリーが表示されます。React コンポーネントのファイルを選択すると、そのコードが「コードエディタ」に表示されます。 「デバッガ」には、JavaScript コードを精査するためのツールが表示されます。 「コードエディタ」で行番号をクリックするとブレークポイントを設置することができます。行番号を右クリックし、ポップアップメニューから適切な項目を選択することで、条件付きブレークポイントやログポイントを追加することができます。 イベントリスナーブレークポイントは、「デバッガ」セクションで追加できます。 イベントリスナーブレークポイントとは、さまざまな状況でアプリをデバッグするためにDevToolsで利用可能な多くのブレークポイントの中の一つです。 ちなみに、Chrome for Developersの「Pause your code with breakpoints」で、さまざまなタイプのブレークポイントについて学ぶことができるので、こちらの記事も読んでいただくと、理解をさらに深めることができます。 さて、コード実行がブレークポイントで一時停止すると、「デバッガ」セクションの「スコープ」タブで、一時停止時点でのローカル変数とグローバル変数の値を確認することができます。 スコープ内にある値は、DevToolsウィンドウの左下にある「コンソール」パネルで参照することができます。コンソールパネルが表示されない場合は、Escキーを押してみることを試してください。 また、「デバッガ」の上部にあるボタンを使用して、コードを一つずつステップ実行し、変数の値がどのように変化するかを確認することができます。これは問題のデバッグに役立ちます。 「BasicCounter」コンポーネントの「Increment」ボタンをクリックした時の状態を下の画像で示します。 stateValue変数が増加しない場合がありますが、これはインクリメント関数内でcount状態の値に設定されているにもかかわらず、予期しない動作かもしれません。 コードをステップ実行することで、「Increment」ボタンがクリックされたときにstateValue変数がゼロのままである理由がわかります。 stateValueは、コンポーネントが再レンダリングされるたびに「0」に設定されます。count状態が増加するため「Increment」ボタンがクリックされるとコンポーネントが再レンダリングされるという仕組みです。 ブで、Chrome 開発者ツールを使用したJavaScriptのデバッグについてさらに学ぶことができます。 ただ、Reactのデバッグ作業をブラウザの開発者ツールだけで補おうとしても限界があります。 開発者ツールのデバッガを使用してReactコンポーネントの状態値を更新することは可能ですが、推奨されません。 Reactのpropsとstateは不変であり、直接変更すべきではありません。 代わりに、React Developer Toolsを使用して状態値やpropsを変更してください。それでは、次にReact Developer Toolsの使用方法について説明します。 React […]

【必読】Webページを読み込む前に高速化する方法

私たちは通常、ブラウザ上に表示されるものを見始めた時や、コンテンツを消費したりページと対話したりできるようになった時に、何が起こるかを測定するという文脈で、Webパフォーマンスについて話します。開発者として、フロントエンド開発者として、Webパフォーマンスは大変重要だからです。例えば、以下のCore Web Vitalsは『私たちが見ることができるもの』、『使用することができるもの』、『経験することができるもの』についての議論を導くものです。 First Contentful Paint(FCP):ユーザーが最初にページを開いてから、コンテンツの一部がレンダリングされるまでの時間のこと Largest Contentful Paint(LCP):ページのロードタイムラインにおいて、ページのメインコンテンツがロードされるまでの時間のこと Interaction to Next Paint(INP):Webページがユーザーの入力にどれだけ速く反応するかを測定する しかし、Webページの最初のバイト(Byte: データのごく小さい単位)がブラウザに受信される前に起こるイベントについてはどうでしょうか? そのようなイベントを測定し、最適化することで、Webページやアプリケーションの読み込みをさらに速くすることは可能でしょうか? Sentryトレースビューを使い、TTFB前のイベントがどのように可視化されるのか Sentryのトレースビューを確認すると、browserウィンドウで何かがレンダリングされる前に起こるイベントがキャプチャされ、[browser]のスパンとしてラベル付けされていることがわかります。キャッシュ、DNS、接続、TLS/SSL、リクエスト、レスポンスの6つのスパンが時系列で登録されています。レスポンス以前のすべてのイベントは、Webページ/リソースへのリクエストからレスポンスの最初のバイトが到着し始めるまでの時間を計測するTTFB(Time to First Byte)に先行します。 Sentryがブラウザで初期化されていないにも関わらず、これらのイベントがどのようにしてSentryが捕らえているのか不思議に思うかもしれません。その答えは、Performance API(Webアプリケーションのパフォーマンスを測定するために使用されるウェブ標準のグループ)にあります。より具体的にいうと、Navigation Timing APIにあります。 本当に素晴らしい点は、ブラウザでパフォーマンス API に直接アクセスできることです。パフォーマンス・エントリーのほとんどは、どのWebページに対しても記録されており、それらを取得するためのセットアップや余分なコードは必要ありません。 開発ツールのコンソールを開き、window.performanceと入力して試してみてください。以下のようなものが表示されます。 ※解析しやすいように、関連するタイムスタンプを手作業でグループ化し、順番に並べています。 それでは、Sentryはどのようにしてブラウザのスパンを読み取っているのでしょうか?パフォーマンスAPIが、URLがブラウザでリクエストされた瞬間からタイムスタンプでこれらのメトリクスを記録する結果、Sentry JavaScript SDKは、初期化後にこれらにアクセスし、Webページがロードされる前に、時系列的に起こったイベントの完全なリストを埋め戻し、トレースビューで可視化できるように、関連する完全なトレースにスパンとして送信することができます。 Webページが読み込まれる前に起きていること window.performanceは、Webページのコンテンツがブラウザに表示されるまでに起こるさまざまなイベントへのウィンドウを提供します。 これはPerformanceオブジェクトを返し、そのオブジェクトは上記のコード例にあるtimingpropertyを含んでいます。これはコードを書かずにページ読み込み時にブラウザによって記録されたイベントを検査する素早い方法ですが、Performance.timingプロパティは現在では非推奨となっており、PerformanceNavigationTiming APIに取って代わりました(これまでのところ、わずかな変更のみです)。 Navigation Timing Level 2仕様のこの図は、ブラウザでナビゲーション要求が行われた瞬間から、現在のドキュメントのロードイベントが完了するまでPerformanceNavigationTimingイベントが記録される順序を示しています。すべてのイベントが各ページのロードで利用できるわけではありませんが、順序は上記のwindow.performanceを使用して観察したものと一致しています! それでは次に、関連する各イベントメトリックを調べてみましょう。 一体、ボンネットの下で何が起こっているのか、そして、トレースビューのブラウザスパンを入力するために、特定のタイムスタンプから Sentry によってどのように計算されるのかを見てみます。そして、この新しい知識を得ることで、TTFBの前にWebパフォーマンスを最適化できるかもしれません。 ブラウザキャッシュ リソースがHTTP GETを使用してフェッチされる場合(例えば、Webページへの標準的なリクエスト)、ブラウザは最初にHTTPキャッシュをチェックします。fetchStartは、ブラウザがキャッシュのチェックを開始する直前の時刻を返します。Sentry Trace Viewのキャッシュスパンは、fetchStartタイムスタンプとdomainLookupStartタイムスタンプの間の時間として計算されます。 トレースビューのキャッシュスパンのゼロでない値は、ブラウザがブラウザキャッシュからリソースを取得するのにかかった時間を表します。キャッシュスパンが長い場合、遅いブラウザや古いブラウザを使用しているか、ブラウザのキャッシュを頻繁にクリアしないユーザである可能性が高いといえます。 ブラウザDNS 次のスパンは、DNS(ドメインネームシステム)のルックアップ時間(ドメイン名をIPアドレスに変換したり、IPアドレスをドメイン名に変換すること)を報告しています。ユーザーがURLをリクエストすると、DNSはデータベース内のドメインを「検索」し、IPアドレスに変換するために問い合わせを行います。これを完了するのにかかった合計時間は、domainLookupEndタイムスタンプ値からdomainLookupStartタイムスタンプ値を引くことで計算されます。 ブラウザ接続 次に、ブラウザがWebサーバに接続するまでの時間を測定します。これは「コネクション・ネゴシエーション」と呼ばれ、connectStart(ブラウザがWebサーバーへの接続を開始するとき)とconnectEnd(Webサーバーへの接続が確立されたとき)の2つのイベント間の時間として測定されます。 […]

モバイル向けセッションリプレイを発表 – オープンβ開始

iOS、Android、React Native用のSession Replayがオープンβになりました。 もしあなたがSession Replayをすでに知っているなら、素晴らしいことです。 リンクをクリックし、あなたのSDKをアップデートすれば、あなたのユーザーが怒りを引き起こすような問題を経験している場所をビデオのように再現してくれるようになります。 もし私が何を言っているのか分からないなら、なおさらです。お話をしましょう。 クラッシュ、悪ふざけ、一般的な無反応は、⭐1つのレビューにつながり、人々はアンインストールし、成長ハックを売り込むPMにつながり、誰もそれを望んでいません。このような悪ふざけを先回りするにはどうすればいいのでしょうか? 昨年、私たちは、Webアプリのユーザーセッションの完全匿名化されたビデオのような複製をキャプチャする機能 – Webベースのアプリケーションのためのセッションリプレイ – を発表しました。現在、40,000を超えるチームが、チェックアウトの不具合、ページの読み込みの遅さ、予期せぬクラッシュなど、あらゆるデバッグにこの機能を使用しています。 何が問題なのかを実際に見ることで、デバッグがより簡単になるとは誰が考えたでしょうか???? モバイル開発者(GitHubで400以上のアップヴォートを提供し、500以上のアーリーアダプターのサインアップに貢献した)もこの機能を望んでいます。 だから、私たちはここにいます。モバイル向けセッション・リプレイは現在オープンベータ版で、アーリーアダプターは無料で使用できます。 コードとUXのギャップを埋める モバイル向けセッションリプレイは、アプリ上のユーザーセッションを視覚的に再現することで、モバイルアプリケーションの可視性を拡大します。これにより、いつ、どこで、どのようにエラーがアプリに影響を及ぼしているかを、自分で再現したり顧客と会話したりすることなく理解することができます。リプレイを使用すると、タップやピンチによるズームなどのジェスチャーがリプレイビューに含まれるため、ユーザーとのインタラクションをより深く理解し、アプリのどこで問題が発生しているかを特定することができます。リプレイには、デバイスタグ、ネットワークリクエストの詳細、スローされた例外などのデバッグコンテキストも含まれています。 当社の全製品と同様に、セッションリプレイはSentryワークフローに統合されています。Issue Detailsでスタックトレースを検査しながら関連するリプレイを見たり、User Feedbackでバグレポートを提出したユーザからのリプレイを見たりすることができます。また、サンプリング設定を構成して、エラーが発生したときのみリプレイをキャプチャし、データのインジェストを減らすことができます。また、UIへの影響やユーザーの反応(アプリを閉じたかどうかなど)によって、問題の深刻度を評価することもできます。 モバイルエラーの根本原因を確認する モバイル用のSentryのセッションリプレイを使用すると、ユーザーがエラーに遭遇したときにサンプリングセッションを優先するオプションがあります。 これは、クラッシュが発生したときに、その特定のエラーに遭遇した実際のユーザーからの関連するリプレイが、問題の詳細ページで関連するSentryの問題に便利にリンクされていることを意味します。エラーの発生前、発生中、発生後に、OSのバージョンや名前などの有用なコンテキストとともに何が起こったかを見ることで、エラーがどのように発生し、ユーザーにどれほどの影響を与えたかを素早く特定することができます。さらに、エラー時のサンプリングにより、必要なデータを待つ時間や、イベントクォータを監視する不安も軽減されます。 ゲーミフィケーションを使用し、UXに重点を置き、素晴らしいイラストやアニメーションがある、派手なライフスタイル・アプリを開発しているとしましょう。アプリケーション・パフォーマンス・モニタリング(APM)製品は、サードパーティのライブラリでクラッシュが発生していることを警告します。この問題を調査し解決するためにセッションリプレイを使用する方法を説明します。 エラーを特定する: エラー追跡システムで、あなたはエラーメッセージ “NullPointerException in run_animation() “で繰り返し起こるクラッシュを分析します。スタック・トレースは、あなたが使っているサードパーティのアニメーション・ライブラリを指していますが、あなたはその意味を理解していません。 関連するセッションのリプレイを探す: リプレイをフィルタリングして、この特定のクラッシュに関連するものだけを表示します。 リプレイを見る: リプレイの1つを選択すると、達成を祝う画面から始まり、達成ポイントが与えられます。かなり長いです)リワードアニメーションが再生される間に、ユーザーは「次へ」ボタンをタップし、アプリがクラッシュします。 コンソールログを調べる: コンソールログの中で、アニメーションライブラリから「onAnimationCancelled」コールバックが呼び出されていることに気づきます。 このコールバックを実装しそこねていたことに気づきます。対策として、アニメーションの時間も短くします。アップデートをデプロイした後、アプリをアップデートするにつれてクラッシュの数が減少していることを監視します。 この例では、Session Replayにより、クラッシュに至ったユーザーアクションを正確に可視化し、エラーの根本原因としてアニメーションライブラリのコールバックの欠落を特定し、この問題を解決するために的を絞った修正を実装することができます。セッション リプレイがなければ、イベントの正確なシーケンスを理解し、このクラッシュの原因を特定することははるかに困難であったでしょう。 アプリのペインポイントの特定 誤解を招くラベル、リンク切れ、パーミッションの問題 – ユーザーが例外を発生させない問題にぶつかることがありますが、それでもユーザー体験に影響を与えます。セッションリプレイは、ユーザーがどこで立ち往生したり、アプリから脱落したりするかを確認することで、アプリ内でこれらのペインポイントが発生する場所を特定するのに役立ちます。 例えば、モバイル e コマースアプリを開発していて、チェックアウト中にアプリが反応しなくなるという悪いレビューが増えているとします。この問題を調査し解決するためにセッションリプレイをどのように利用できるかを説明しましょう。 アプリのパフォーマンスに問題があると思われます。しかし、パフォーマンスKPIはまだ良好で、APM製品はチェックアウト画面で問題を示しません。 関連するセッション・リプレイを見つける:リプレイをフィルタリングして、チェックアウト画面に関連するリプレイのみを表示し、継続時間の長いリプレイにも注目します。 リプレイを見る:リプレイの1つを選択し、ユーザーのアクションを観察します。ユーザーがチェックアウトページの「次へ」ボタンをタップし、サーバーへのAPIコールが開始されるのを確認します。 ネットワークリクエストを確認する: ネットワーク・タブを調べると、APIコールが正常かつ適切な時間で終了していることがわかります。これで、これが根本的な原因ではないことがわかりました。 パンくずを調べる:アプリのUI状態管理でごく最近の状態変更があり、APIコールが返された後に状態が衝突してUIが更新されないことに気づきます。この時点で、ユーザーは激怒してクリックし、最終的にアプリを終了します。 修正と検証:UI状態管理のバグを処理するための修正を実装します。アップデートをデプロイした後、後続のセッションリプレイを監視して、ユーザーがチェックアウトプロセス中に進めるようになったことを確認します。 […]

Reactでフェッチウォーターフォールを特定する方法

フェッチウォーターフォールは、複数のフェッチリクエストが並列ではなく、逐次的に呼び出されるシナリオです。これは深刻なパフォーマンス低下につながります。 以下にその様子を示します。 この場合、2番目と3番目のリクエストは並行してフェッチされ、ページロードとデータ表示が4.053秒改善されます。フェッチウォーターフォールによるパフォーマンスへの悪影響は、スタッキングでも発生します。つまり、リクエストが多ければ多いほど、パフォーマンスへの影響は悪化します。 この記事では、トレースを使用してReactアプリケーションのフェッチウォーターフォールを特定する方法を見ていきます。 トレース入門 トレースとは、あるプロセスやフローを定義する操作やコマンドの論理的なグループを記述するスパンの階層からなるデバッグ・データ・セットをキャプチャするために、コードを「インスツルメンテーション」するプロセスのことです。ページのロードを例にとってみましょう。 ページロードを操作の流れとして記述しようとすると、(おおよそ)次のようになるはずです。 ブラウザがサーバーにページをリクエストする サーバーはHTMLで応答し、ブラウザはそれを解析する パース中に、ブラウザはリンクされたJSファイルに出くわす。JSファイルにはReactとページコードが含まれているので、ブラウザはそれを実行する。 ブラウザは、ページコードの指示に従ってコンポーネントのフェッチとレンダリングを行う。 さらに、ブラウザーは画像、ファビコン、CSSファイルなどのリソースをリクエストする。 これらの処理はすべて特定の順序で行われますが、その時間はデバイスの処理能力やインターネット接続の速度などの要因によって異なります。 この記事のトップにあるスクリーンショットは、APIにHTTPリクエストを送信する3つのhttp.clientスパンを示しています。それぞれ、特定の開始時刻、特定の終了時刻、そして雑多なデータが添付されています。上のスクリーンショットのトレース・ビューを見ると、3つのHTTPリクエストが次々と実行されていることがよくわかります。 プロジェクトの設定 まず、ReactプロジェクトにSentryをセットアップする必要があります。始めるには、Sentry React SDKをインストールする必要があります。 この時点で、すでにサインアップしているはずです。新しいReactプロジェクトを作成しましょう。 Create Project」ボタンを押すと、React SDKのインストール方法と初期化方法が表示されます。初期化設定は以下のようにします。 Sentry SDKの最も優れた点は、コードベースの大部分を自動的に計測してくれることです。フェッチのような既知の操作を自動的にスパンでラップし、Sentryインスタンスに送信するので、すぐにデータの検査を開始できます。 これで、アプリをデプロイして、ユーザーがアプリを使用している間に測定された実際のパフォーマンスデータを得ることができます。データが得られれば、フェッチウォーターフォールのようなパフォーマンスの問題を特定するための調査を始めることができます。 Reactでフェッチウォーターフォールを識別するには? フェッチウォーターフォールの症状には、著しく遅いページロードが含まれるため、不審に遅いページロードを警戒する必要があります。 Performanceページを使用すると、疑わしい遅いページロードを簡単にピックアップして検査することができます。以下は、私たちのアプリのインデックスページのPerformanceページのスクリーンショットで、ユーザーが私たちのページを訪問している間にキャプチャされたトランザクションを示しています。 どのスパンが不審に遅いか、はっきりとわかります。そのうちの1つをクリックすると、トレース・ビュー画面が表示され、すべてのスパンを見ることができます。http.clientのスパンを拡大してよく見ると、ウォーターフォールが見えます。 この場合、3番目のリクエストグループは、どの結果にも依存しないので、2番目のリクエストの終了を待つ必要はありません。つまり、フェッチウォーターフォールを分解すると、2秒の改善を見ていることになります。 フェッチウォーターフォールを修正するには、その原因を調べる必要があります。フェッチウォーターフォールはサーバーに原因があることもあります。フェッチ・ウォーターフォールのよくあるケースの修正方法についてもっと知りたい方は、「Reactにおけるフェッチウォーターフォール」の記事をご覧ください。 これを見ると、トレースを使って他のタイプの問題も解決できると思うかもしれません。そして、それは正しいでしょう!トレースは本当に一般的なデバッグ手法で、Web Vitalの不具合、ネットワークの遅延、サーバーレスアプリケーションのコールドスタート、キャッシュの欠落やキャッシュ機構の問題、その他様々な問題やバグを特定し、デバッグし、修正するのに役立ちます。トレースは、”トレース “をたどって、いつ何が起こったか、どれくらいの時間がかかったかを調べるようなデバッグや修正に使うことができます。 結論 つまり、トレースはフェッチウォーターフォールの特定に役立つということです。 簡単に復習しましょう。 トレースとはデバッグテクニックの一つで、ページロードのような操作の流れを視覚化しやすくするために、デバッグデータをキャプチャすることです。 トレースとは、互いに関連し、開始時刻と終了時刻を持ち、任意のデータが付加されたスパンのコレクションです。 アプリケーションでトレースのキャプチャを始めるために、私たちはSentryのReact SDKをインストールし、アプリのトップで初期化し、変更を単純にデプロイしました。SDKは自動的にアプリをインスツルメンテーションするので、トレースデータをすぐに見ることができました。 キャプチャされたトレースをすべてリストアップし、その継続時間に基づいて、どのトレースが不審に遅いかを確認できました。 遅いページロードを検査すると、最適化するとページロードを秒単位で改善できるフェッチウォーターフォールが見つかりました。 この記事が、トレースとは何か、どのように始めるべきかを理解する助けになれば幸いです。それでは、よいトレースを!     IchizokuはSentryと提携し、日本でSentry製品の導入支援、テクニカルサポート、ベストプラクティスの共有を行なっています。Ichizokuが提供するSentryの日本語サイトについてはこちらをご覧ください。またご導入についての相談はこちらのフォームからお気軽にお問い合わせください。

Trace Viewを使用してAPIコールを22.3秒短縮した方法

Dan Mindruはフロントエンド開発者兼デザイナーで、モーニング・メーカー・ショーの共同司会者でもあります。 現在、PageUI、Clobbr、CronToolなどのアプリケーションを開発しています。 開発者として、遅いAPIほどイライラさせられるものはありません。 コードが動くことは分かっていても、それがもう良いユーザー体験にならないことは分かっているはずです。 私にもそのようなことがあり、2週間ほど見て見ぬふりをしていました。 しかししばらくすると、いくつかの問題は個人的なものになります。 問題は、どこから手をつければいいのか見当もつかなかったことです。 Sentryの新しいトレース・ビューを発見するまでは。 もちろん、トレースこそ、パフォーマンス低下の根本原因を突き止めるために必要なものです。では、このトレース・ビューのトリックひとつで、APIコールのロード時間を22.3秒短縮した方法をお教えしましょう。 この投稿で詳細を説明し、トレースを使って自分のAPIコールのボトルネックを見つける方法を紹介します。うまくいけば、あなた自身のレスポンスタイムを数秒短縮できるかもしれません。さあ、始めましょう! トレースビューとは? ほとんどの人は、Sentryのエラー監視機能を知っています。しかし、それだけではありません。実際、Sentryはパフォーマンスのボトルネックを見つけるのにも役立ちます! Sentryのセットアップがいかに簡単かは前にも述べました。その後、Sentryはパフォーマンス・メトリクスも収集してくれます。 トレース・ビューはその重要な一部で、トランザクションとスパンを滝のように可視化します。ご想像の通り、これはアプリケーションのパフォーマンスに影響を与える遅延、関連するエラー、ボトルネックの特定に役立ちます。 次に、私のユースケースでこれをどのようにセットアップしたかをお見せしましょう。 面白いことに、Sentryは自社のパフォーマンス測定機能を活用したことで、年間16万ドルを節約しました! ファイルI/Oのトレースビューの設定 私がデバッグしているエンドポイントは、普通のボトルネックではありません。長いHTTPコール、ファイルI/O、サードパーティ・コール(AI生成)、そして最後にDBクエリーがいくつかあります。 問題のエンドポイントはShipixenというアプリのもので、コードベース全体、リポジトリ、コンテンツを生成し、Vercelにデプロイまでしてくれます。 見ての通り、通常のCRUDエンドポイントではありません。 このような状況は、影響を測定することなく毎月毎月機能を増やし続けるエンドポイントによく見られます。 最終的なエンドポイントのボスと呼んでもいいでしょう。 目の前の問題を理解する ただひとつわかっていたのは、このリクエストのすべてのステップが必要だということでした。バックグラウンド処理にしたり、キューに分けたり、他のアーキテクチャを応用することも考えたが、実際のところは以下の通りです。 ユーザーが利益を得るのは、すべてのタスクが完了してから。 ユーザーは王様/女王様であり、私のアーキテクチャなど気にも留めない。 私は行動を共にし、リクエストを完了するのにかかる時間を半分にするよう努力する必要がある。 これが、44.94秒という短い処理時間の理由です。 あるいは、平均的なシナリオでこのリクエストを完了するのにかかった時間です。 さっそくデバッグシューズを履いて、トレースビューを開いてみました。驚いた! SentryはネットワークI/Oの検出はうまくやりましたが、それ以外はすべてブラックボックスでした。 そしてそれは理にかなっています。 実行中の様々なファイルI/Oをすべてトレースする必要があることを、どうやって知ることができるでしょうか? 54秒かかったという事実は無視して、目の前の問題に集中しましょう。どのタスクに一番時間がかかるのか、さらに重要なのは、どの順番でタスクが完了するのかがわからなかったのです。 カスタム計装の設定 幸運なことにSentryはカスタムインスツルメンテーションを行うメソッドを公開しているので、ファイルシステム上であれ、https上であれ、その中間であれ、あらゆる操作を追跡することができます。 スパンを作成する関数呼び出しで、問題の操作をラップする必要があります。スパンとは、基本的に時間の計測値であり、「起こること」です。”thing “と呼ぶのは少し抽象的なので、スパンと呼ぶことにしました。 お使いの言語やフレームワークにもよりますが、以下のようになります。 そして、メソッドをスパンで囲み始めると、いつの間にかトレース・ビューワーはこのようになっていました。 ボトルネックを特定する方法を探ってみましょう。 ボトルネックの特定 この見方をよく見てみましょう。一般的に、これらは最も注意すべき問題です。 ロング・ラン・スパン ペイロードを減らすことができるか? 複数の並列タスクに分割できるか? バックグラウンドで実行できるか? より高速で効率的な新しいAPIはないか? 互いに待機するウォーターフォール型スパン(並列化可能) 互いに待機しなければならない非効率的なスパンオーダー スパン間の依存関係 最初のバイトまでの時間が遅い / ネットワーク依存のコールドスタート […]

JavaScript v8 SDKにおけるOpenTelemetryとNodeサポートの改善

Sentry Launch Weekで初めて発表したように、私たちはJavaScript SDKのメジャーリリースに向けて取り組んできました。 このアップデートにより、Sentry JavaScript SDKをさらに簡単に使い始めることができます。このリリースは、自動instrumentationを提供するフレームワークとライブラリの数を広げます。しかし、Sentryのセットアップをカスタマイズしたい場合、OpenTelemetry (OTel)の拡張サポートにより、必要なcustom configurationを85行のコードから10行以下に減らしました。 OpenTelemetryによるトレース OpenTelemetry はスタンダードな機能とメンテナンス機能を提供してくれますが、それらのツールと収集されたデータを使って、あなたに洞察を提供するのは私たちの役目です。 例えば、Sentry の新しいトレース・ビューは、v8 の改良された Node.js サポートの恩恵も受ける最新の機能改良の一つに過ぎません。 私たちのNode SDKにOTelを組み込むことで、以前のバージョンよりも詳細なスパンデータを収集します。 Next.jsとPrisma 4で構築されたSentry独自のChangelogに記録されたスパンの詳細をご覧ください。 より多くのNodeフレームワークとライブラリの自動インストルメンテーション 特にOTelのNode SDKは、Sentryの以前のNode SDKよりも多くのNodeフレームワークを自動パフォーマンス計測のためにサポートしています。Node SDKの一部をOTelに置き換えることで、SentryがデフォルトでサポートするNode.jsフレームワークとライブラリのサポートを拡大しました。 これは、あなたのNodeプロジェクトに以下のフレームワークやライブラリがある場合、Sentry Node SDKが自動的にそれらを検出し、設定することを意味します。 Express(改善) Connect(改善) Nest.js(新規) Koa(改善) Fastify(新規) Hapi(新規) ライブラリ pg (Postgres) pg-native (Postgres) mongodb (Mongo) mongoose (Mongo) mysql2 (MySQL) mysql (MySQL) graphql (GraphQL) apollo-server-core (Apollo) @nestjs/graphql (Apollo) Prisma […]

2024年にGoogle Lighthouseのスコアをハックする方法

Google Lighthouseは、開発者の間でWebページのパフォーマンスをゲーム化し、促進する最も効果的な方法の1つです。Lighthouseを使えば、全体的なパフォーマンス、アクセシビリティ、SEO、Googleが考える「ベストプラクティス」に基づいてWebページを評価することができます。 これらのテストは、フロントエンドフレームワークのすぐに使えるパフォーマンスを評価したり、熱心なリファクタリングによってパフォーマンスが改善されたことを喜んだりするのに使うかもしれません。そして、Lighthouseの満点のスクリーンショットをソーシャルメディアで共有するのが好きなのはご存じでしょう。紙吹雪のお祝いにふさわしい栄誉です。 Lighthouseが私たちのような開発者にパフォーマンスについて語らせるという事実だけでも勝利です。しかし、パーティーの片棒を担ぐようなことはしたくないですが、実際のところ、Webパフォーマンスはこれよりもはるかに微妙なものです。 この記事では、Google Lighthouseがどのようにパフォーマンス・スコアを算出しているかを検証し、この情報を使って、私たちに有利になるようにスコアを「ハック」してみます。Lighthouseをどこまで 「騙す 」ことができるか、そして自分たちにふさわしいスコアよりも良いスコアを出すことができるか、楽しみながらやってみましょう。 その前に、データについて話しましょう。 現場データは重要である ローカル・パフォーマンス・テストは、Webサイトのパフォーマンスが正しい方向に傾いているかどうかを理解するための素晴らしい方法ですが、現実の全体像を描くことはできません。WWW(ワールドワイドウェブ)は西部の荒野であり、人々がWebサイトにアクセスするために使用しているさまざまなデバイスの種類、インターネット接続速度、画面サイズ、ブラウザ、およびブラウザのバージョン(これらすべてがページパフォーマンスとユーザー体験に影響を与える可能性があります)を、私たちはほぼ確実に見失っています。 Sentryのようなアプリケーションパフォーマンス監視ツールによって、実際にWebサイトを使用している人々のデバイスから収集されたフィールドデータ(しかも大量に)は、制御された条件下でハイスペックなスーパーパワー開発マシンを使用して、1サンプルサイズから収集されたラボデータよりもはるかに正確なWebサイトパフォーマンスのレポートを提供します。フィリップ・ウォルトンは2021年、HTTPアーカイブのデータに基づき、「Lighthouseで100点を獲得したページのほぼ半数が、推奨されるCore Web Vitalsのしきい値を満たしていなかった」と報告しています。 パフォーマンスとは、単一のCore Web Vitals指標やLighthouseのパフォーマンススコア以上のものです。私たちが話しているのは、扱う生データの種類をはるかに超えるものです。 Webパフォーマンスは数字以上のもの Webパフォーマンスについて話すとき、スピードが最初に話題に上ることがよくあります。これは測定する上で最悪なことではありませんが、スピードはおそらくビジネスのKPIや売上目標に大きく影響されることを念頭に置かなければなりません。 Googleが2018年に発表したレポートによると、ページの読み込み時間が3秒以上になると、直帰する確率が32%増加し、10秒になると123%に跳ね上がるといいます。 つまり、より多くの売上につなげるには、直帰率を減らす必要があるという結論になります。そして、直帰率を減らすには、ページの読み込みを速くしなければなりません。 しかし、「読み込みを速くする」とはどういうことなのでしょうか? ある時点で、Webページの読み込みをこれ以上速くすることは物理的に不可能になります。人間やそれをつなぐサーバーは世界中に散らばっており、現代のインターネット・インフラは一度に多くのバイト数しか配信できないのです。 要するに、ページの読み込みは一瞬ではないということです。スピードとは何か?Googleのいう、ページ読み込みイベントとは。 単一の指標では完全には捉えられない体験のことです。ユーザーが「速い」と感じるかどうかには、読み込み体験の間に複数の瞬間があり、1つの瞬間だけに注目すると、残りの時間に起こる悪い体験を見逃してしまうかもしれません。 ここでのキーワードは『体験』です。本当のWebパフォーマンスとは、数字やスピードよりも、ユーザーとしてページロードやページの使いやすさをどのように体験するかということなのです。そしてこれは、Google Lighthouseがどのようにパフォーマンススコアを計算するかという議論にうまくつながっていく。(あなたが思っているよりも、純粋なスピードは重要ではありません)。 Google Lighthouseのパフォーマンススコアはどのように計算されますか? (CLS))と、ページ読み込みのタイムライン全体を通して観察可能なその他のスピード関連メトリクス(Speed Index (SI)、Total Blocking Time (TBT))に基づくスコアを加重平均して算出されます。 このように、メトリクスは総合スコアで重み付けされます。 各スコアに割り当てられた重み付けは、Googleが優れたユーザー体験のさまざまな構成要素にどのような優先順位をつけているかを教えてくれます。 1. Webページはユーザーの入力に反応しなければならない この指標は、FCP(First Contentful Paint)後の合計時間を調べ、メインスレッドがユーザー入力への迅速な応答を妨げるほど長くブロックされている可能性がある場所を示すのに役立ちます。メイン スレッドで JavaScript タスクが 50 ミリ秒以上実行されると、メイン スレッドは「ブロックされた」と見なされます。TBTを最小化することで、Webページが物理的なユーザー入力(例:キーの押下、マウスのクリックなど)に確実に反応するようになります。 2.Webページは、予期せぬ視覚的な変化を伴うことなく、有用なコンテンツを読み込むべきである Lighthouseのメトリクスで次に重みがあるのは、Largest Contentful Paint(LCP)とCumulative Layout Shift(CLS)です。LCPは、ページのロードタイムラインの中で、ページのメインコンテンツがロードされた可能性が高い時点を示すもので、そのため有用です。 メインコンテンツがロードされた可能性が高い時点で、ユーザーがページを使用でき、予期しないビジュアルシフト(CLS)の影響を受けないように、ビジュアルの安定性も維持したいものです。良いLCPスコアは2.5秒未満です(私たちはWebサイトを可能な限り高速化しようとしていることが多いので、これは想像以上に高いスコアです)。 […]

バックエンドが原因で遅くなったWebページのデバッグ手法について

開発者として、誰かがあなたのWebサイトの読み込みが遅いと言ったとき、あなたはどんな反応をすべきでしょうか? 「ユーザーに任せている」と言わない限り、あなたはすでに正しい道を歩んでいます。ユーザーの苦痛を和らげることを選択したのですから、読み込みの遅さやパフォーマンスの問題を特定し、修正するプロセスをご案内します。 実際、パフォーマンスの問題をどのように解決するかはさまざまですが、開発者としては、解決への最短経路を常に求めています。 小規模から中規模の静的サイトであれば、ブラウザの開発ツールに組み込まれているLighthouseスコアで十分でしょう。個々のページのCore Web Vitalsが表示され、通常、Webサイトのパフォーマンスを改善するために必要な変更を行うのに十分な情報が得られます。とはいえ、Lighthouseのスコアだけを目標にすべきではありません。 Webサイトが成長したり、静的でなくなったりすると、パフォーマンスの問題をデバッグするために、より詳細な洞察が必要になります。 この投稿では、私が開発したサイトを紹介します。このサイトは静的Webサイトとは程遠く、各ルートは人気リズムゲームのゲーム内スコアに基づいて、ユーザーにカスタムされたポケモンのようなカードを動的にレンダリングします。 そのような動的な性質をもつため、すべてのブラウザとユーザーが使用する可能性のある・すべてのネットワークで・すべてのルートをテストすることは不可能です。 その代わりに、実際のユーザーによる実際のセッションのパフォーマンスをモニターして、いつ問題が発生し、どのように解決できるかを知る必要があります。 問題の発見 モニタリングツールがなければ、ドッグフーディング(アプリを自分で使用すること)、またはユーザーレポートという2つの方法のいずれかでパフォーマンスの問題に遭遇する可能性が高いです。 ドッグフーディングは重要ですが、インターネット接続が良好なハイエンドのデバイス1台でしかアプリを使用していない可能性が高く、それがユーザーの間で一般的かどうかを検討する必要があります。ユーザーレポートは非常に有用ですが、正直なところ、明らかなレポートチャネルを持っていない場合、それらはほとんどありません(そして、その場合でも、役に立たないか、または再現するのが難しい場合があります)。 常にログを読み、リクエストのタイミングを計っていない限り、どこで間違ったのか、なぜ間違ったのかを正確に突き止めることは難しいのです。 Sentryのユーザーフィードバックとセッションリプレイ Sentryでは、あなたのサイトに常に存在するユーザーフィードバックウィジェットにオプトインすることができます。 このウィジェットは、ユーザーが見つけたバグを直接Sentryのダッシュボードに報告することができ、スクリーンショットを追加するオプションもあるので、即座に実用的な洞察を得ることができます。 さらに、Sentryは、このフィードバックを「セッションリプレイイベント」と連動させ、ユーザーがボタンをクリックしたり、サイト内を移動するたびに、追加の有用な詳細を含むパンくずなど、ユーザーのWebサイトとのインタラクションの完全な再現を見ることができます。 最近、Sentryのウィジェットを介してユーザーがフィードバックを送信し、ロードに時間がかかる理由を尋ねたとき、私はWebサイトのページロードが遅いことに気づきました。セッションのリプレイをチェックすると、明らかに読み込みが非常に遅かったのですが、フィードバックとセッションのリプレイで提供された情報でも、大きな画像や過剰なJavaScriptのような明らかな問題や迅速な解決策を見つけることができませんでした。この問題については、Sentryのトレースビューをもう少し深く掘り下げる必要がありました。 トレースの使用 Sentryのトレース機能は、フロントエンドからバックエンド、そしてサービス間のトランザクションをリンクし、ソフトウェアの接続されたビューを提供することで、コードのパフォーマンスを追跡するために使用されるツールです。 トレースビューは、各トランザクションにかかる時間から、より具体的な問題のデバッグを助けるためにユーザが使用したデバイスやブラウザまで、あらゆる情報を提供します。トレースビューは、ユーザーフィードバックや問題によってトリガーされたリプレイにも添付され、ユーザーがページをロードしたとき、ボタンをクリックしたとき、サイト内を移動したときなど、舞台裏で起こったすべてのことを簡単に調べることができます。 セッションリプレイイベントのトレースを参照した後(パフォーマンスタブを少し調べると同時に)、私のサイトの(かなりひどい)スローダウンはナビゲーション中のロード関数にあることがわかりました。それはいいことですが、私は15分以上前にコードを書いたのです。幸運なことに、Sentryはリクエストまでの詳細をすぐに提供してくれました。 修正 リピート・リクエスト 私が犯した最初のミスは、それを書くときに明らかであったはずなのですが、不必要に同じリクエストを何度も繰り返し、一度に一つのものだけを取り出すことでした。ユーザー」オブジェクトを構築する際に、大きなJSONデータの塊から特定のプロパティを取り出す必要があったのですが、1回の関数呼び出しで必要なプロパティを返すのではなく、同じ関数を8回繰り返し呼び出して配列を作成し、その都度1つのプロパティしか取得しませんでした。 Sentryのトレースビューで、私はすぐに問題を特定することができました。 青い 「自動グループ化された 」スパン(2秒近くかかりました🤮)が最初に目に留まり、それを拡大して各スパンが同じリクエストエンドポイントを持っているのを見ると、私のコードで何が修正されるべきかは明白でした。 リクエストウォーターフォール さてさて、滑稽なほど酷いコードはこのくらいにして、解決策があまり明確でない問題に移りましょう。上の画像では、「自動グループ化された 」リクエストの先にも、ページロードの終わりまで小さな階段があるのがお分かりいただけるでしょう。これはリクエストウォーターフォールと呼ばれるもので、リクエスト(この場合は外部APIへのリクエスト)を直列に行い、前のリクエストを終えてから次のリクエストを開始することで発生するものです。 このウォーターフォールはできるだけ避けたいものですが、リクエストを連続して行う必要がある状況もあります(一般的には、ある呼び出しのリクエストが前の呼び出しの結果に依存している場合)。 1回の呼び出しで楽曲IDのリストを取得しているのですが、より具体的な情報を取得するには、特定のIDごとに個別のリクエストを行う必要があります。私が最初に考えたのは、1回のリクエストですべての情報を集めることはできないので、1つずつ呼び出す必要があり、現在持っているパフォーマンスはそのままになってしまうということでした。幸いなことに、この問題を抱えたのは私が初めてではなく、リクエストのウォーターフォールを回避する2つの解決策を見つけました。 直列運転と並列運転 ロード時間のパフォーマンスを最適化する場合、リクエストを直列に実行しないことが最も重要ですが、常に可能というわけではありません。直列に実行する必要があるときと、そうでないときを見分けることが重要です。 なぜなら、可能な限りリクエストを並行して実行する必要があるからです。 直列実行の反対は並列実行で、その名の通り、すべてのリクエストが同時に実行され、最も遅いリクエストが終了するたびにグループとして解決されます。JavaScriptでは、コード上の違いはごくわずかですが、実行時に実際に起こることは大きく異なります。 上記のように、リクエストを直列に呼び出すコードから並列に呼び出すコードに変更した後、最終的に恐ろしいウォーターフォールを取り除くことができ、Sentryでこれを確認することができます。両方のロード関数のトレースを比較すると、かつては階段状だったものが、今では崖のようになっており、最も遅いリクエストが終了するとすぐにページがロードされることがわかります。リクエストの処理方法を変更した後、P75(75%のユーザーにとっての平均ページ読み込み速度)を6.5秒からわずか2.3秒まで下げることができました。 一歩前進 SvelteKit(またはReactではこのようなもの)のpromiseストリーミングを使えば、このパフォーマンスの大幅な向上をさらに一歩進めることが可能になります。 サーバーのロード関数からクライアントにpromiseをストリーミングすることで、すべてのリクエストが終了する前にページをレンダリングできるようになります。これには累積レイアウトシフト(Cumulative Layout Shift)の可能性に対処する複雑さが加わりますが、ページのロード速度を劇的に改善する機会があり、ユーザーにとって最も重要なデータをより迅速に利用できるようになります。 パフォーマンスには価値がある この記事の冒頭で、最も早く解決する道は常に取るべき道であると述べました。 パフォーマンスの問題は、「バグ 」ではないという点でユニークであり、Webサイトのエラーやクラッシュを引き起こしていないため、多くの開発者が見過ごしてしまうことがあります。しかし、一貫して速い読み込み速度は、10,000セッションに1回起こるエッジケースエラーよりも、ユーザーにとって同じように、いやそれ以上に重要です。Sentryを使用することで、このような抽象的な問題の発見と解決が非常に簡単になります。 パフォーマンス問題のデバッグの詳細 Sentryのトレースがパフォーマンス問題のデバッグにどのように役立つのか、もっと知りたいですか? 悪いLCPスコアをバックエンドの問題にトレースするSalmaのブログ記事をチェックするか、以下のワークショップの全容をぜひご覧ください。     IchizokuはSentryと提携し、日本でSentry製品の導入支援、テクニカルサポート、ベストプラクティスの共有を行なっています。Ichizokuが提供するSentryの日本語サイトについてはこちらをご覧ください。またご導入についての相談はこちらのフォームからお気軽にお問い合わせください。

;