Chrome Developer Toolsでパフォーマンスを最適化
パフォーマンスチューニングの基礎:プロファイリング
2023年4月3日
著者: 竹洞 陽一郎
はじめに
Webパフォーマンスチューニングは、WebアプリケーションやWebサイトのパフォーマンスを向上させるために実施される最適化手法の一連です。
効果的なパフォーマンスチューニングを実現するには、正確なプロファイリング情報が欠かせません。
フロントエンドの品質管理では、プロファイリングを利用して時間消費別のパレート図を作成し、最も時間を消費している部分から改善を開始します。
パフォーマンスチューニングに詳しくない方向けに、Lighthouseが利用できます。
ただし、実務におけるパフォーマンスチューニングでは、Lighthouseだけではボトルネックの特定が難しいことがあります。
これからWebパフォーマンスチューニングを始める方や、現在Webパフォーマンスチューニングに取り組んでいる方には、Chrome Developer Toolsのパフォーマンスタブを活用することを強くお勧めします。
本記事では、Chrome Developer Toolsのパフォーマンスタブを使用する理由について詳しく解説します。
リアルタイムのフィードバック
Chrome Developer Toolsのパフォーマンスタブは、リアルタイムでフィードバックを提供します。
これにより、デバッグや最適化のプロセスがスムーズに進行し、変更がパフォーマンスにどのような影響を与えるかを即座に確認できます。
一方、Lighthouseはレポートを生成するまでに時間がかかるため、同じような迅速なフィードバックは得られません。
特にプロファイリング作業においては、コードを書き換えた際に、どの程度、パフォーマンスが変わるのかを確認する必要があります。
Chrome Developer Toolsには、ソースコードのオーバーライド機能が提供されており、ローカル環境でコードの書き換えて、その影響を分析できます。
この機能により、本番環境やステージング環境などのコードを書き換えることなく、改善したコードが有効か確認できます。
より詳細な情報
Chrome Developer Toolsのパフォーマンスタブは、実行中のスクリプト、ネットワークアクティビティ、レンダリングパフォーマンスなど、Webページのパフォーマンスに関連する詳細な情報を提供します。
これにより、パフォーマンスのボトルネックや問題点を特定しやすくなります。
Lighthouseでは、パフォーマンスの概要と改善提案が提供されますが、具体的な問題箇所を特定するための情報は限定的です。
フロントエンドのパフォーマンス改善において、皆さんが一番に知りたいのは、「どのJavaScriptの関数で時間を最も消費しているのか?」でしょう。
Chrome Devloper Toolsのパフォーマンスタブを使えば、明確に、どのJavaScriptファイルの何行目の関数であるかが、簡単に判明します。
カスタマイズ可能な設定
Chrome Developer Toolsのパフォーマンスタブでは、ネットワークやCPUのスロットリング設定をカスタマイズできます。
これにより、異なるデバイスや接続条件下でのパフォーマンスを簡単にシミュレートすることができます。
一方、Lighthouseでは、プリセットされた設定に基づいて評価が行われるため、同じような柔軟性はありません。
Lighthouseのデフォルト設定は、低速4Gスロットリングです。
(RTTが150ms、下りの帯域幅は1.6Mbps)
しかし、現在の国内の4G回線は、LTE Advanced Proの規格によって、レイテンシは20~60ms、下り100Mbps以上を実現しているため、シミュレーションとしては適切でないことがわかります。
さらに、パフォーマンスチューニングにおいては、最も高速な環境を用意することが重要です。
これは品質管理の「局所管理化」においても大切な考え方で、遅い回線でプロファイリングを行うと、Webサイトの遅さが回線の問題なのか、フロントエンド周りの処理が原因なのかを特定しにくくなります。
Chrome Developer Toolsを使用する際には、高速な光回線、優れた性能のCPU、十分なメモリを搭載したマシンで実施しましょう。
最善の環境でWebサイトが遅い場合は、遅さが確実であり、ボトルネックを見つけやすくなります。
パフォーマンスタイムラインの可視化
Chrome Developer Toolsのパフォーマンスタブでは、Webページのロードプロセスをフレームワークに応じたタイムラインとして可視化することができます。
これにより、どの処理がどのタイミングで実行されているかを一目で確認でき、遅延や不具合の原因を特定しやすくなります。
Lighthouseでは、このようなタイムラインの可視化は提供されていません。
パフォーマンスタイムラインでは、遅延は、以下の図のように、計算処理の遅延とダウンロードの遅延の2つに分かれます。
計算処理の遅延は、基本的にJavaScriptの計算処理の遅延です。
ダウンロードの遅延は、空白になります。
重要な点として、一見ダウンロードの遅延に見える場合でも、実際には何らかの計算処理による影響があることがよくあります。
- 明示的にsetTimeout関数を使って指定秒数で遅延させている場合。
このようなケースでは、明示的なミリ秒指定を避け、イベントベースの処理に書き換えましょう。 - JavaScript処理やCSS Background Imageの使用による画像の読込遅延がある場合。
この場合、imgタグに書き換えて、decoding="async"属性を追加することを検討しましょう。 - XHR(XMLHttpRequest)など、古い方法でファイルをダウンロードしている場合。
このようなケースでは、fetch関数に書き換えることが推奨されます。
例えば、setTimeout関数を使用している場合、コードの最適化が必要かもしれません。
リファクタリングを行い、DOMContentLoadedやloadイベントの発火をEventListenerで検出して実行する方法に書き換えましょう。
このような関数や変数を探す際には、Ctrl+Shift+Fを押してWebページ全体検索を活用することで、簡単に見つけることができます。
ここで、パフォーマンスタブでパフォーマンス解析に役立つ3つのビューをご紹介しましょう。
- ボトムアップ
- 時間消費が長い順で表示
- 呼び出しツリー
- 呼び出しの順番での表示
- イベントログ
- 発生したイベントを時系列で表示
ボトムアップ
「ボトムアップ」(Bottom-Up)とは、プロファイリング結果を関数呼び出しのコストに基づいて表示するビューです。
ボトムアップビューは、Webページのパフォーマンスに最も影響を与えている関数や処理を特定するのに役立ちます。
ボトムアップビューでは、プロファイリング期間中に記録された関数呼び出しを、自己時間(Self Time)と合計時間(Total Time)の両方でソートして表示します。
自己時間は、関数自体の実行に費やされた時間を示し、合計時間は、その関数とその子関数(関数が呼び出す他の関数)の実行に費やされた時間の合計を示します。
このビューを利用することで、Webページのパフォーマンスに影響を与えるボトルネックや問題箇所を特定し、最適化のための具体的なアクションを決定することができます。
たとえば、自己時間が高い関数は、最適化の対象として検討する価値があります。
また、合計時間が高い関数は、その子関数の最適化によってパフォーマンスが向上する可能性があります。
パフォーマンスタイムラインで、特定の遅延している画像やCSSなどを選択した状態でボトムアップを確認すると、その画像やCSSと依存関係を持つ処理を消費時間順で確認することができます。
最も消費時間が長い依存関係から解放することが、高速化に繋がります。
呼び出しツリー
「呼び出しツリー」(Call Tree)は、プロファイリングデータを階層的な構造で表示するビューです。
このビューは、Webページ上で実行された関数の呼び出し関係や実行時間を把握するのに役立ちます。
呼び出しツリーでは、関数の呼び出しは親子関係で表示されます。
親関数は子関数を呼び出し、子関数はさらに他の関数を呼び出すことができます。
各関数は、実行にかかった時間(自己時間と合計時間)と、呼び出された回数を表示します。
このビューを利用することで、以下のような情報を得ることができます。
- 関数呼び出しの階層構造
- どの関数がどの関数を呼び出しているかを確認できます。
これにより、処理のフローを把握し、最適化の対象となる関数を特定できます。 - 関数の実行時間
- 自己時間と合計時間を比較することで、関数自体の実行時間と子関数の実行時間の違いを把握できます。
これにより、最適化が必要な部分を特定しやすくなります。 - 呼び出し回数
- 関数が呼び出される回数を確認できます。
高い呼び出し回数を持つ関数は、最適化の効果が大きい可能性があります。
呼び出しツリーを使用することで、Webページのパフォーマンスに影響を与える関数や処理を特定し、効果的な最適化戦略を立てることができます。
パフォーマンスタイムラインで、特定の遅延している画像やCSSなどを選択した状態で呼び出しツリーを確認すると、その画像やCSSと依存関係を持つ処理を呼び出し順で確認することができます。
階層関係を追いかけて、大元になっている関数を特定することが可能となります。
イベントログ
「イベントログ」(Event Log)は、Webページ上で発生したイベント(アクションやインタラクション)の詳細なリストを提供するビューです。
このビューは、Webページの実行中に記録されたイベントを時系列順で把握するのに役立ちます。
このビューを利用することで、以下のような情報を得ることができます。
- イベントのタイプ
- 例えば、JavaScriptの関数呼び出し、ネットワークリクエスト、DOM操作、レイアウト計算、ペイント(レンダリング)、リソースのロードなど。
- イベントのタイムスタンプ
- イベントが発生した時点での時間。
- イベントの詳細
- イベントに関連する追加情報。
例えば、関数呼び出しの場合は関数名や引数、ネットワークリクエストの場合はURLやHTTPステータスコードなど。
イベントログを利用することで、Webページの実行中に発生したイベントの詳細を確認し、問題の特定やデバッグ、最適化に役立てることができます。
イベントログは、特定のイベントが発生したタイミングや頻度、関連する情報を把握する際に特に有用です。
また、イベントログを使って、予期しないイベントや無駄なイベントが発生していないかを確認することもできます。
パフォーマンスタイムラインで、特定の遅延している画像やCSSなどを選択した状態でイベントログを確認すると、その画像やCSSの読み込みに際して発生したイベントを時系列で確認することができます。
処理に必要のないイベントと関係を持っていないかを確認することが可能となります。
ユーザーインタラクションの分析
Chrome Developer Toolsのパフォーマンスタブを使用することで、ユーザーインタラクションに関連するパフォーマンス問題を特定しやすくなります。
例えば、ボタンのクリックやページのスクロールに対する応答速度を計測し、イベントハンドラやアニメーションの最適化が必要かどうかを判断できます。
Lighthouseでは、ユーザーインタラクションに関する詳細な分析は提供されていません。
Chrome Developer Toolsでプロファイリングする際の注意事項
シークレットウィンドウで行う
通常のChromeのウィンドウで行うと、アドオン関連の影響を受けます。
Ctrl+Shift+Nで、必ずシークレットウィンドウで行い、シークレットウィンドウでアドオンが動かないようにしましょう。
キャッシュを無効化する
Chrome Developer Toolsのネットワークタブでキャッシュの無効化に必ずチェックを入れましょう。
フロントエンド周りのパフォーマンスチューニングにおいては、キャッシュを前提にしないことが大事です。
初回訪問で遅いと、ユーザは直帰することがデータから分かっているからです。
ネットワークタブのデータを鵜呑みにしない
ネットワークタブで、各ファイルのダウンロードを確認して、Webフォントや画像などが遅延しているから、軽量化が必要と軽率に判断しないようにしましょう。
Catchpointだと、オブジェクト計測が可能で、画像単体とかWebフォント単体での計測が可能です。
OS付属のコマンドでも、レンダリング処理やJavaScriptの処理が関与してない状態で計測してみましょう。
macOSやLinux
cURLを使って、計測できます。
curl -o /dev/null -s -w "Connect: %{time_connect}s\nStart transfer: %{time_starttransfer}s\nTotal: %{time_total}s\n" "https://perfdata.jp/images/logo.png"
すると、以下のように表示され、Totalの箇所の0.039306秒=39.306msだと分かります。
Connect: 0.010176s Start transfer: 0.037917s Total: 0.039306s
Windows
PowerShellのInvoke-WebRequestを使ってリクエストを行い、Measure-Commandで計測できます。
Measure-Command {Invoke-WebRequest -Uri "https://perfdata.jp/images/logo.png"}
すると、以下のように表示され、TotalMillisecondsの箇所の29.5345msだと分かります。
Days : 0 Hours : 0 Minutes : 0 Seconds : 0 Milliseconds : 29 Ticks : 295345 TotalDays : 3.41834490740741E-07 TotalHours : 8.20402777777778E-06 TotalMinutes : 0.000492241666666667 TotalSeconds : 0.0295345 TotalMilliseconds : 29.5345
ネットワークタブで遅くても、オブジェクト計測で高速であれば、確実にCSSやJavaScriptなどの処理と依存関係を持っています。
パフォーマンスタブで、遅延している画像をクリックして、ボトムアップ、呼び出しツリー、イベントログを確認した方が良いでしょう。
まとめ
これらの理由から、Chrome Developer Toolsのパフォーマンスタブは、フロントエンドのWebパフォーマンスチューニングにおいて、Lighthouseよりも優れた選択肢であると言えます。
リアルタイムフィードバック、詳細な情報提供、カスタマイズ可能な設定、パフォーマンスタイムラインの可視化、およびユーザーインタラクションの分析が、効果的なパフォーマンスチューニングを実現する上での強力なサポートとなります。
Chrome Developer Toolsのパフォーマンスタブを活用し、パフォーマンスチューニングに不可欠なプロファイリングスキルを向上させましょう。