チュートリアルの目標
このチュートリアルでは、Chrome DevTools を使用してウェブサイトの読み込みを高速化する方法を紹介します。
続いて、このチュートリアルの動画をご覧ください。
前提条件
ウェブ開発の概要のクラスで学んだ内容と同様に、ウェブ開発に関する基本的な経験を積む必要があります。
読み込みのパフォーマンスについて知っている必要はありません。
はじめに
トニーです。トニーは猫の社会で非常に有名です。また、ファンが自分の好きな食べ物を紹介できるウェブサイトも作成しています。ファンはサイトを気に入っていますが、サイトの読み込みが遅いという苦情が何度も寄せられています。トニーからサイトの速度を上げるように頼まれました。
ステップ 1: サイトを監査する
サイトの読み込みパフォーマンスの改善に着手する際は、常に監査から始めてください。監査には 2 つの重要な機能があります。
- これにより、その後の変化を測定するためのベースラインが作成されます。
- 最も効果が大きい変更に関する実用的なヒントが得られます。
設定
まず、Tony のウェブサイト用に新しい作業環境を設定して、後で変更できるようにする必要があります。
ウェブサイトのプロジェクトを Glitch でリミックスしてください。新しいプロジェクトがタブで開きます。このタブのことを「エディタタブ」と呼びます。
プロジェクトの名前は tony からランダムに生成された名前に変わります。これで、コードの編集可能なコピーが用意されました。後でこのコードに変更を加えます。
エディタタブの下部にある [プレビュー] > [新しいウィンドウでプレビュー] をクリックします。デモが新しいタブで開きます。このタブを [デモ] タブと呼びます。サイトの読み込みに時間がかかることがあります。
デモとともに DevTools を開きます。
ベースラインを確立する
ベースラインは、パフォーマンスの改善を実施する前のサイトのパフォーマンスの記録です。
[Lighthouse] パネルを開きます。
[その他のパネル] の後ろに隠れている場合があります。Lighthouse のレポート設定とスクリーンショット設定を一致させます。各オプションの説明は次のとおりです。
- check_box [ストレージを消去] をタップします。このチェックボックスをオンにすると、すべての監査の前に、ページに関連付けられているストレージがすべて消去されます。サイトを初めて訪問したユーザーの行動を監査したい場合は、この設定をオンのままにします。同じサイトをもう一度訪問したい場合は、この設定を無効にします。
- check_box JS サンプリングを有効にする。このオプションはデフォルトではオフになっています。有効にすると、詳細な JavaScript コールスタックがパフォーマンス トレースに追加されますが、レポートの生成が遅くなる可能性があります。トレースは、Lighthouse レポートが生成された後、more_vert の [Tools] メニュー > [View Unthrottled Trace] から使用できます。
- スロットリングのシミュレーション(デフォルト) 。このオプションは、モバイル デバイスでの一般的なブラウジング環境をシミュレートします。「シミュレーション」と呼ばれるのは、監査プロセス中に Lighthouse が実際にスロットリングされないためです。モバイル条件下でページの読み込みにかかる時間を推定するにすぎません。一方、DevTools のスロットリング(高度)の設定では、実際には CPU とネットワークがスロットリングされますが、監査プロセスが長くなるというトレードオフがあります。
- [モード] > [3 つのモードをご覧ください。 ナビゲーション(デフォルト)]:このモードでは 1 回のページ読み込みが分析されるため、このチュートリアルではこれを必要とします。詳細については、
- [デバイス] > [ モバイル] をタップします。モバイル オプションでは、ユーザー エージェント文字列が変更され、モバイル ビューポートをシミュレートします。デスクトップ オプションでは、モバイルでの変更が無効になります。
- [カテゴリ] > check_box パフォーマンス。有効なカテゴリが 1 つだけの場合、Lighthouse では対応する監査のセットのみを含むレポートが生成されます。他のカテゴリから提供される推奨事項のタイプを確認したい場合は、有効のままにしておきます。関連性のないカテゴリを無効にすると、監査プロセスが若干早くなります。
[ページ読み込みを分析] をクリックします。10 ~ 30 秒後に、[Lighthouse] パネルにサイトのパフォーマンス レポートが表示されます。
レポートエラーの処理
Lighthouse レポートでエラーが発生した場合は、他のタブを開かずにシークレット ウィンドウでデモタブを実行してみてください。これにより、Chrome をクリーンな状態から実行できます。特に Chrome 拡張機能は監査プロセスを妨げる可能性があります。
レポートの見方
レポートの上部にある数字は、サイトの全体的なパフォーマンス スコアです。後でコードを変更すると、この数値が増加します。スコアが高いほどパフォーマンスが優れていることを意味します。
指標
[指標] セクションまで下にスクロールし、[ビューを開く] をクリックします。指標に関するドキュメントを読むには、[詳細] をクリックします。
このセクションでは、サイトのパフォーマンスを定量的に測定します。各指標から、パフォーマンスのさまざまな側面に関する分析情報が得られます。たとえば、First Contentful Paint は、コンテンツが最初に画面に描画されたタイミングを示します。これは、ユーザーがページ読み込みを認識する際の重要なマイルストーンであり、Time to Interactive は、ページがユーザー操作を処理するのに十分な準備が整っている時点を示します。
スクリーンショット
次は、ページの読み込み時にどのように表示されるかを示す一連のスクリーンショットです。
オポチュニティ
次は [最適化] セクションで、このページの読み込みパフォーマンスを向上させるための具体的なヒントを提供します。
オポチュニティをクリックすると、詳細が表示されます。
[詳細...] をクリックすると、最適化案が重要である理由と、その解決方法に関する具体的な推奨事項を確認できます。
診断
[診断] セクションでは、ページの読み込み時間に影響する要素に関する詳細情報を確認できます。
合格した監査
[合格した監査] セクションには、サイトの評価が表示されます。クリックしてセクションを展開します。
ステップ 2: テスト
Lighthouse レポートの [Opportunities](最適化)セクションで、ページのパフォーマンスを向上させるためのヒントを確認できます。このセクションでは、コードベースに推奨される変更を実装し、変更のたびにサイトを監査して、サイトの速度への影響を測定します。
テキスト圧縮を有効にする
レポートによると、テキスト圧縮を有効にすることは、ページのパフォーマンスを向上させるうえで特に有効な方法の一つです。
テキスト圧縮とは、ネットワーク経由で送信する前に、テキスト ファイルのサイズを縮小(圧縮)することです。たとえば、メールを送信する前にフォルダを zip 圧縮してサイズを小さくする方法などです。
圧縮を有効にする前に、テキスト リソースが圧縮されているかどうかを手動でチェックする方法がいくつかあります。
[ネットワーク] パネルを開き、[大きいリクエスト行を使用する] を確認します。
[設定] >各 [Size] セルには 2 つの値が表示されます。一番上の値は、ダウンロードされたリソースのサイズです。一番下の値は、圧縮されていないリソースのサイズです。2 つの値が同じ場合、そのリソースはネットワーク経由で送信される際に圧縮されていません。この例では、bundle.js
の上限と下限の値はどちらも 1.4 MB
です。
リソースの HTTP ヘッダーを調べて、圧縮の有無を確認することもできます。
bundle.js をクリックし、[ヘッダー] タブを開きます。
[Response Headers] セクションで
content-encoding
ヘッダーを検索します。bundle.js
は圧縮されていません。これは表示されないはずです。リソースが圧縮されている場合、このヘッダーは通常、gzip
、deflate
、またはbr
に設定されます。これらの値の説明については、ディレクティブをご覧ください。
説明はこれで十分です。変更してみましょう。数行のコードを追加して、テキスト圧縮を有効にします。
エディタタブで
server.js
を開き、次の 2 行(ハイライト部分)を追加します。... const fs = require('fs'); const compression = require('compression'); app.use(compression()); app.use(express.static('build')); ...
app.use(express.static('build'))
の前にapp.use(compression())
を配置してください。Glitch がサイトの新しいビルドをデプロイしてくれるのを待ちます。左下隅の幸せな絵文字は、デプロイが成功したことを示します。
前に学習したワークフローを使用して、圧縮が機能していることを手動で確認します。
デモタブに戻り、ページを再読み込みします。
[Size] 列には、テキスト リソース(
bundle.js
など)について 2 つの異なる値が表示されます。bundle.js
の269 KB
の最上位の値はネットワーク経由で送信されたファイルのサイズで、1.4 MB
の最下位の値は圧縮されていないファイルサイズです。bundle.js
の [Response Headers] セクションにcontent-encoding: gzip
ヘッダーが含まれるようになりました。
ページで Lighthouse レポートを再度実行し、テキスト圧縮がページの読み込みパフォーマンスに及ぼす影響を測定します。
[Lighthouse] パネルを開き、上部のアクションバーで [Perform an audit...] をクリックします。
設定は前と同じままにして、[ページの読み込みを分析] をクリックします。
おめでとうございます!進歩があるように見えます。全体的なパフォーマンス スコアが高くなっているはずです。これは、サイトの読み込み速度が上がっていることを意味します。
実際のテキスト圧縮
ほとんどのサーバーには、圧縮を有効にするためのこのような簡単な修正があります。テキストの圧縮に使用するサーバーの構成方法を調べてみてください。
画像のサイズ変更
新しいレポートによると、画像の適切なサイズ調整も大きなチャンスです。
画像のサイズを変更すると、画像のファイルサイズが小さくなるため、読み込み時間を短縮できます。ユーザーが 500 ピクセル幅のモバイル デバイスの画面で画像を表示している場合、1, 500 ピクセル幅の画像を送信しても意味がありません。最大で 500 ピクセル幅の画像を送信するのが理想的です。
レポートで [適切なサイズの画像] をクリックして、サイズ変更が必要な画像を確認します。4 枚の画像すべてが必要以上に大きいようです。
エディタタブに戻り、
src/model.js
を開きます。const dir = 'big'
をconst dir = 'small'
に置き換えます。 このディレクトリには、サイズ変更された同じ画像のコピーが格納されます。ページを再度監査して、この変更による読み込みのパフォーマンスへの影響を確認します。
この変更による全体的なパフォーマンス スコアへの影響はわずかなようです。ただし、ユーザーを保存しているネットワーク データの量はスコアから明確に表示されません。古い写真の合計サイズは約 6.1 MB でしたが、現在は約 633 KB しかありません。これは、[ネットワーク] パネルの下部にあるステータスバーで確認できます。
現実世界での画像のサイズ変更
小規模なアプリの場合は、このような 1 回限りのサイズ変更で十分かもしれません。しかし大規模なアプリでは明らかに スケーラブルではありません大規模なアプリで画像を管理するための戦略には、次のものがあります。
- ビルドプロセス中にイメージのサイズを変更します。
- ビルドプロセス中に各イメージのサイズを複数作成し、コードで
srcset
を使用します。実行時には、ブラウザがデバイスに最適なサイズを選択します。相対的なサイズの画像をご覧ください。 - リクエストに応じて動的に画像のサイズを変更できる画像 CDN を使用する。
- 少なくとも、各画像を最適化してください。多くの場合、これによって大幅な費用削減が可能になります。最適化とは、画像ファイルのサイズを小さくする特別なプログラムを通じてイメージを実行することです。その他のヒントについては、重要な画像の最適化をご覧ください。
レンダリングをブロックするリソースを排除する
最新のレポートによると、レンダリングをブロックするリソースを排除することが、今や最大のチャンスであることがわかりました。
レンダリング ブロック リソースとは、ブラウザがページを表示する前にダウンロード、解析、実行する必要がある外部の JavaScript ファイルまたは CSS ファイルです。目標は、ページを正しく表示するために必要なコア CSS と JavaScript コードのみを実行することです。
最初のタスクは、ページの読み込み時に実行する必要がないコードを見つけることです。
[レンダリングをブロックするリソースを排除する] をクリックして、ブロックしているリソース(
lodash.js
とjquery.js
)を確認します。ご使用のオペレーティング システムに応じて、次のキーを押してコマンド メニューを開きます。
- Mac: Command+Shift+P
- Windows、Linux、ChromeOS: Ctrl+Shift+P
「
Coverage
」と入力して [一致率を表示] を選択します。ドロワーに [カバレッジ] タブが開きます。
[ 再読み込み] をクリックします。[カバレッジ] タブには、ページの読み込み中に
bundle.js
、jquery.js
、lodash.js
で実行されているコードの量の概要が表示されます。このスクリーンショットは、jQuery ファイルと Lodash ファイルの約 74% と 30% がそれぞれ使用されていないことを示しています。
jquery.js 行をクリックします。DevTools で、[Sources] パネルでファイルを開きます。横に緑色のバーが表示されていれば、そのコード行は実行されています。コード行の横に赤いバーが表示されている場合は、そのコードが実行されておらず、ページの読み込み時に絶対に必要とされていないことを示します。
jQuery コードを少しスクロールします。「実行される」行には、実際にはコメントのみが含まれるものもあります。コメントを削除するミニファイアでこのコードを実行すると、このファイルのサイズを小さくできます。
つまり、独自のコードを扱う場合は、[カバレッジ] タブを使用すると、コードを行ごとに分析し、ページの読み込みに必要なコードのみを配布できます。
jquery.js
ファイルと lodash.js
ファイルはページを読み込むためにも必要ですか?[リクエストのブロック] タブでは、リソースが利用できない場合の動作を確認できます。
- [Network] タブをクリックし、コマンド メニューをもう一度開きます。
「
blocking
」と入力して [Show Request Blocking] を選択します。[リクエストのブロック] タブが開きます。[ パターンを追加] をクリックし、テキスト ボックスに「
/libs/*
」と入力し、Enter キーを押して確定します。ページを再読み込みします。jQuery リクエストと Lodash リクエストは赤色で表示され、これはブロックされたことを表します。ページは引き続き読み込まれ、インタラクティブであるため、これらのリソースは特に必要ないようです。
[ パターンをすべて削除] をクリックして、
/libs/*
ブロック パターンを削除します。
一般に、[リクエストのブロック] タブは、特定のリソースが利用できないときのページの動作をシミュレートする場合に便利です。
次に、これらのファイルへの参照をコードから削除し、ページを再度監査します。
- エディタタブに戻り、
template.html
を開きます。 対応する
<script>
タグを削除します。<head> ... <meta name="viewport" content="width=device-width, initial-scale=1"> <script src="/libs/lodash.js"></script> <script src="/libs/jquery.js"></script> <title>Tony's Favorite Foods</title> </head>
サイトの再構築と再デプロイが完了するまで待ちます。
[Lighthouse] パネルからページを再度監査します。総合スコアが回復しているはずです。
実際の環境におけるクリティカル レンダリング パスの最適化
クリティカル レンダリング パスとは、ページの読み込みに必要なコードのことを指します。一般に、ページの読み込み中には重要なコードのみを配布し、それ以外はすべて遅延読み込みを行うことで、ページの読み込みを高速化できます。
- 完全に削除できるスクリプトが見つかることはまずありませんが、ページ読み込み時にリクエストする必要はなく、代わりに非同期でリクエストできるスクリプトが多数見つかることがよくあります。async または defer の使用をご覧ください。
- フレームワークを使用している場合は、本番環境モードがあるかどうかを確認します。このモードでは、重要なレンダリングをブロックしている不要なコードを取り除くために、ツリー シェイキングなどの機能を使用することがあります。
メインスレッドの処理を減らす
最新のレポートの [Opportunities] セクションには、少額のコスト削減の可能性が示されていますが、[診断] セクションまで下にスクロールすると、最大のボトルネックはメインスレッド アクティビティが多すぎることがわかります。
メインスレッドは、HTML、CSS、JavaScript の解析と実行など、ページの表示に必要なほとんどの作業をブラウザが行う場所です。
目標は、[Performance] パネルを使用して、ページの読み込み中にメインスレッドが行っている処理を分析し、不要な作業を遅らせるか削除する方法を見つけることです。
[Performance] > [ Capture Settings] を開き、[Network] を [Slow 3G] に、[CPU] を [6x speeddown] に設定します。
モバイル デバイスは通常、ノートパソコンやデスクトップ パソコンよりもハードウェアの制約が多いため、これらの設定により、性能の低いデバイスを使用しているかのようにページを読み込むことができます。
[ 再読み込み] をクリックします。 DevTools でページが再読み込みされ、そのページを読み込むために必要なすべての操作が可視化されます。この可視化をトレースtraceと呼びます。
トレースには、アクティビティが左から右に時系列で表示されます。上部の FPS、CPU、NET のグラフには、1 秒あたりのフレーム数、CPU アクティビティ、ネットワーク アクティビティの概要が表示されます。
[Overview] セクションに表示された黄色の部分は、CPU がスクリプト アクティビティにより完全にビジー状態であったことを意味します。これは、JavaScript の作業を減らすことでページの読み込みを高速化できる手がかりになります。
トレースを調査して、JavaScript の処理を減らす方法を見つけます。
[タイミング] をクリックして展開します。
React にはカスタム速度の測定方法がたくさんありますが、トニーのアプリは React の開発モードを使用しているようです。React の本番環境モードに切り替えると、おそらく簡単にパフォーマンスを向上させることができます。
もう一度 [タイミング] をクリックすると、セクションが閉じます。
[Main] セクションに移動します。このセクションでは、メインスレッドのアクティビティが左から右に時系列で表示されます。Y 軸(上から下)には、イベントが発生した理由が示されます。
この例では、
Evaluate Script
イベントによって(anonymous)
関数が実行され、それに伴って__webpack__require__
が実行され、さらに./src/index.jsx
が実行されました。[Main] セクションの一番下までスクロールします。フレームワークを使用する場合、上位アクティビティの大部分はフレームワークによって発生し、通常は制御できません。通常、アプリによって発生したアクティビティは一番下に表示されます。
このアプリでは、
App
という関数がmineBitcoin
関数の呼び出しを多数発生させているようです。トニーはファンのデバイスを使って暗号通貨のマイニングを行っているようですね...下部の [ボトムアップ] タブを開きます。このタブには、最も時間がかかったアクティビティの内訳が表示されます。[Bottom-Up] セクションに何も表示されない場合は、[Main] セクションのラベルをクリックします。
[ボトムアップ] セクションには、現在選択されているアクティビティまたはアクティビティ グループの情報のみが表示されます。たとえば、
mineBitcoin
アクティビティのいずれかをクリックした場合、[ボトムアップ] セクションには、そのアクティビティに関する情報のみが表示されます。[セルフ時間] 列には、各アクティビティに直接費やした時間が表示されます。この例では、メインスレッドの時間の約 82% が
mineBitcoin
関数に費やされています。
本番環境モードを使用して JavaScript アクティビティを減らすと、ページの読み込みが速くなるかどうかを確認してみましょう。本番環境モードで開始します。
- エディタタブで
webpack.config.js
を開きます。 "mode":"development"
を"mode":"production"
に変更します。- 新しいビルドがデプロイされるまで待ちます。
ページを再度監査します。
mineBitcoin
の呼び出しを削除して、JavaScript アクティビティを削減します。
- エディタタブで
src/App.jsx
を開きます。 constructor
のthis.mineBitcoin(1500)
の呼び出しをコメントアウトします。- 新しいビルドがデプロイされるまで待ちます。
- ページを再度監査します。
いつものように、Largest Contentful Paint 指標や Cumulative Layout Shift 指標を減らすなどの対応が必要です。
現実世界でメインスレッドの動作を減らす
一般に、[パフォーマンス] パネルは、サイトの読み込み時に実行されるアクティビティを把握し、不要なアクティビティを削除する方法を見つける最も一般的な方法です。
console.log()
に近いアプローチを使用したい場合は、User Timing API を使用すると、アプリのライフサイクルの特定のフェーズを任意にマークアップして、各フェーズの所要時間を追跡できます。
まとめ
- サイトの読み込みパフォーマンスの最適化に着手する場合は、常に監査から始めてください。監査によってベースラインが確立され、改善方法のヒントが提供されます。
- 変更を 1 つずつ実施し、変更ごとにページを監査して、個別の変更がパフォーマンスにどのように影響するかを確認します。
次のステップ
自分のサイトで監査を実施するレポートの解釈についてサポートが必要な場合や、読み込みのパフォーマンスを向上させる方法については、以下のリンクから DevTools コミュニティのサポートをご利用ください。
- このドキュメントのバグについては、developer.chrome.com リポジトリで報告してください。
- Chromium のバグで DevTools のバグレポートを報告します。
- メーリング リストで機能と変更点について議論する。サポートに関する質問にメーリング リストを使用しないでください。代わりに Stack Overflow を使用してください。
- Stack Overflow で、DevTools の使用方法に関する全般的なヘルプを入手できます。バグを報告する際は、必ず Chromium バグを使用してください。
- @ChromeDevTools でツイートしてください。