Lighthouse: ウェブサイトの速度を最適化する

Kayce Basques 氏
Kayce Basques
ソフィア・エメリアノバ
Sofia Emelianova

チュートリアルの目標

このチュートリアルでは、Chrome DevTools を使用してウェブサイトの読み込みを高速化する方法を紹介します。

このチュートリアルの続きを読むか、動画をご覧ください。

前提条件

このウェブ開発の概要クラスで学習しているものと同様の、基本的なウェブ開発の経験が必要です。

読み込みパフォーマンスについて認識しておく必要はありません。

はじめに

トニーと申します。トニーは猫の社会でとても有名です。ファンが好きな食べ物を知ることができるウェブサイトを作成しました。彼のファンはこのサイトを気に入っていますが、サイトの読み込みが遅いという苦情を何度も耳にしています。トニーから、サイトの速度を上げるのを手伝ってほしいと言われました。

猫のトニー。

ステップ 1: サイトを監査する

サイトの読み込みパフォーマンスの改善に着手する場合は、必ず監査から始めます。監査には 2 つの重要な役割があります。

  • 後続の変更を測定するためのベースラインが作成されます。
  • どの変更が最も効果的かについての実用的なヒントを確認できます。

設定

まず、Tony のウェブサイト用に新しい作業環境を設定して、後で変更できるようにする必要があります。

  1. ウェブサイトのプロジェクトを Glitch でリミックスします。新しいプロジェクトがタブで開きます。このタブは [エディタタブ] と呼びます。

    元のソースと [リミックス] をクリックした後のエディタのタブ。

    プロジェクトの名前は tony からランダムに生成された名前に変わります。これで、編集可能な独自のコードのコピーが作成されます。後でこのコードを変更します。

  2. エディタタブの下部にある [プレビュー] > [新しいウィンドウでプレビュー] をクリックします。新しいタブでデモが開きます。このタブはデモタブと呼ばれます。サイトの読み込みに時間がかかることがあります。

    [デモ] タブ。

  3. デモと一緒に DevTools を開きます

    DevTools とデモです。

ベースラインを確立する

ベースラインは、パフォーマンスを改善する前にサイトのパフォーマンスを記録したものです。

  1. [Lighthouse] パネルを開きます。 その他のパネルの背後に隠れている場合があります。

    Lighthouse パネル。

  2. Lighthouse のレポートの構成設定を、スクリーンショットの設定と照合してください。各オプションの説明を以下に示します。

    • [空き容量を増やす] をタップします。このチェックボックスをオンにすると、すべての監査の前に、ページに関連付けられているすべてのストレージが消去されます。初めてサイトを訪れたユーザーのエクスペリエンスを監査する場合は、この設定をオンのままにします。サイトに繰り返しアクセスするには、この設定を無効にします。
    • シミュレートされたスロットリング(デフォルト) 。このオプションは、モバイル デバイスでの通常のブラウジング条件をシミュレートします。Lighthouse では実際に監査プロセス中にスロットリングが行われないため、「シミュレート」と呼ばれます。モバイルの環境でページの読み込みに要する時間を推定するだけです。一方、[DevTools のスロットリング(高度)] 設定では、実際には CPU とネットワークがスロットリングされますが、監査プロセスが長くなります。
    • [モード] > [ ナビゲーション(デフォルト)]。このモードでは 1 回のページの読み込みを分析します。このチュートリアルではそれが必要です。詳細については、3 つのモードをご覧ください。
    • [デバイス] > [ モバイル]。モバイル オプションは、ユーザー エージェント文字列を変更し、モバイル ビューポートをシミュレートします。PC 版では、モバイルの変更を無効にするだけです。
    • [カテゴリ] > [ パフォーマンス]。有効なカテゴリが 1 つしかない場合、対応する監査セットのデータのみを含むレポートが生成されます。他のカテゴリが提供する最適化案の種類を確認したい場合は、有効にしたままにすることができます。無関係なカテゴリを無効にすると、監査プロセスが若干早くなります。
  3. [ページ読み込みを分析] をクリックします。10 ~ 30 秒後に [Lighthouse] パネルにサイトのパフォーマンスに関するレポートが表示されます。

    サイトのパフォーマンスに関する Lighthouse のレポート。

レポートエラーの処理

Lighthouse のレポートでエラーが発生した場合は、他のタブを開かずにシークレット ウィンドウからデモタブを実行してみてください。これにより、Chrome をクリーンな状態から実行できます。特に、Chrome 拡張機能は監査プロセスの妨げになる可能性があります。

エラーのあるレポート

レポートの見方

レポートの上部にある数字は、サイトの全体的なパフォーマンス スコアです。その後、コードを変更すると、この数値が増加します。スコアが高いほど、パフォーマンスが高くなります。

全体的なパフォーマンス スコア。

指標

[指標] セクションまで下にスクロールし、[ビューを開く] をクリックします。指標に関するドキュメントを読むには、[詳細] をクリックします。

[指標] セクション。

このセクションでは、サイトのパフォーマンスの定量的な測定結果を確認できます。各指標は、パフォーマンスのさまざまな側面に関する分析情報を提供します。たとえば、First Contentful Paint は、コンテンツが最初に画面にペイントされたタイミング(ユーザーがページ読み込みを認識する上での重要なマイルストーン)であるのに対し、Time To Interactive は、ページがユーザーの操作を処理できるほど表示される状態になった時点を示します。

スクリーンショット

次に、読み込まれたページがどのように表示されるかを示すスクリーンショットのコレクションがあります。

読み込み中のページがどのように表示されるかを示すスクリーンショット。

商談

次の [最適化] セクションには、この特定のページの読み込みパフォーマンスを改善するための具体的なヒントが表示されます。

[オポチュニティ] セクション。

最適化案をクリックすると、詳細が表示されます。

テキスト圧縮の可能性に関する詳細情報。

[詳細] をクリックすると、最適化案が重要な理由と、最適化案の修正方法に関する具体的な推奨事項に関するドキュメントが表示されます。

診断

[診断] では、ページの読み込み時間に影響する要素について詳しく確認できます。

診断セクション。

監査に合格

[合格した監査] セクションには、サイトが適切に行われていることが表示されます。クリックしてセクションを展開します。

「合格した監査」セクション。

ステップ 2: テスト

Lighthouse レポートの [最適化案] セクションでは、ページのパフォーマンスを改善するためのヒントを確認できます。このセクションでは、推奨される変更をコードベースに実装し、変更ごとにサイトを監査してサイトの速度に及ぼす影響を測定します。

テキスト圧縮を有効にする

レポートには、テキスト圧縮の有効化がページのパフォーマンス向上につながる大きな機会の 1 つと記載されています。

テキスト圧縮とは、ネットワーク経由でテキスト ファイルを送信する前に、そのファイルのサイズを縮小(圧縮)することです。これは、フォルダをメールで送信する前に圧縮してサイズを小さくする、といったことです。

圧縮を有効にする前に、テキスト リソースが圧縮されているかどうかを手動で確認する方法をいくつかご紹介します。

[ネットワーク] パネルを開き、 [設定] > [リクエスト行が大きい] チェックボックスをオンにします。

大きなリクエスト行が表示されている [ネットワーク] パネルの [サイズ] 列。

Size セルには 2 つの値が表示されます。一番上の値は、ダウンロードされたリソースのサイズです。下部の値は、非圧縮リソースのサイズです。2 つの値が同じであれば、リソースはネットワーク経由で送信されるときに圧縮されません。この例では、bundle.js の上下の値はどちらも 1.4 MB です。

リソースの HTTP ヘッダーを調べることで、圧縮されているかどうかを確認することもできます。

  1. [bundle.js] をクリックして [Headers] タブを開きます。

    [Headers] タブ。

  2. [レスポンス ヘッダー] セクションで content-encoding ヘッダーを検索します。これは表示されない、つまり bundle.js が圧縮されていないことを意味します。リソースが圧縮されている場合、このヘッダーは通常、gzipdeflate、または br に設定されます。これらの値の説明については、ディレクティブをご覧ください。

説明は以上です。変更を加えるときです。テキスト圧縮を有効にするには、以下の数行のコードを追加します。

  1. エディタタブで server.js を開き、次の 2 行(ハイライト表示された行)を追加します。

    ...
    const fs = require('fs');
    const compression = require('compression');
    
    app.use(compression());
    app.use(express.static('build'));
    ...
    
  2. app.use(express.static('build')) の前に app.use(compression()) を追加してください。

    server.js の編集。

  3. Glitch がサイトの新しいビルドをデプロイするのを待ちます。左下に表示される笑顔の絵文字は、デプロイに成功したことを示します。

前に学習したワークフローを使用して、圧縮が機能していることを手動で確認します。

  1. デモタブに戻り、ページを再読み込みします。

    これで、Size 列には bundle.js などのテキスト リソースについて 2 つの異なる値が表示されるようになりました。bundle.js269 KB の値の上部はネットワーク経由で送信されたファイルのサイズ、1.4 MB の下部の値は非圧縮のファイルサイズです。

    [Size] 列にテキスト リソースの 2 つの異なる値が表示されるようになりました。

  2. bundle.js の [レスポンス ヘッダー] セクションに content-encoding: gzip ヘッダーが含まれるようになりました。

    [Response Headers] セクションに、content-encoding ヘッダーが追加されました。

該当ページで Lighthouse レポートを再度実行して、テキスト圧縮がページの読み込みパフォーマンスに与える影響を測定します。

  1. [Lighthouse] パネルを開き、上部のアクションバーで [追加] をクリックします。 [Perform an audit...] をクリックします。

    [Perform an audit] ボタン。

  2. 前と同じ設定のままにして、[ページ読み込みを分析] をクリックします。

    テキスト圧縮を有効にした後の Lighthouse レポート。

おめでとうございます!進歩しているようです。全体的なパフォーマンス スコアが上がっているはずです。つまり、サイトの速度が上がっているということです。

実際のテキスト圧縮

ほとんどのサーバーでは、圧縮を有効にするために、このような簡単な修正が行われています。テキストを圧縮するために使用するサーバーの構成方法を検索してください。

画像のサイズ変更

新しいレポートでは、画像のサイズを適切に調整することも大きなチャンスだと言っています。

画像のサイズを変更すると、画像のファイルサイズが小さくなり、読み込み時間を短縮できます。ユーザーがモバイル デバイスの画面で幅 500 ピクセルの画像を表示しているのであれば、1, 500 ピクセル幅の画像を送信しても意味がありません。最大 500 ピクセル幅の画像を送信するのが理想的です。

  1. レポートで [画像のサイズを適切にする] をクリックして、サイズ変更が必要な画像を確認します。4 枚はすべて必要以上に大きいようです。

    「画像のサイズを適切にする」機能に関する詳細

  2. エディタタブで src/model.js を開きます。

  3. const dir = 'big'const dir = 'small' に置き換えます。 このディレクトリには、サイズ変更されたのと同じ画像のコピーが含まれています。

  4. ページを再度監査して、この変更が読み込みのパフォーマンスにどう影響するかを確認します。

    画像サイズ変更後の Lighthouse レポート。

この変更による全体的なパフォーマンス スコアへの影響は少ないようです。ただし、ユーザーを保存しているネットワーク データの量は、スコアから明らかではありません。古い写真の合計サイズは約 6.1 MB でしたが、現在は約 633 KB です。これは、[ネットワーク] パネルの下部にあるステータスバーで確認できます。

画像サイズ変更の前後に転送されるデータの量。

現実世界で画像のサイズ変更を行う

小規模なアプリでは、このように 1 回限りのサイズ変更を行うだけで十分かもしれません。しかし 大規模なアプリでは明らかに 拡張性がありません大規模なアプリで画像を管理するための戦略を以下にいくつか示します。

  • ビルドプロセス中にイメージのサイズを変更します。
  • ビルドプロセス中に各イメージのサイズを複数作成して、コードで srcset を使用します。ブラウザは、実行時にデバイスに最適なサイズを選択します。相対サイズ画像をご覧ください。
  • リクエスト時に画像を動的にサイズ変更できる画像 CDN を使用する。
  • 少なくとも、各画像を最適化してください。多くの場合、これにより大幅なコスト削減が可能です。最適化とは、画像ファイルのサイズを小さくする特別なプログラムを介して画像を実行することです。その他のヒントについては、重要な画像の最適化をご覧ください。

レンダリング ブロック リソースを排除する

最新のレポートでは、レンダリングを妨げるリソースを排除することが、今や最大の機会であると述べています。

レンダリング ブロック リソースとは、ページを表示する前に、ブラウザでダウンロード、解析、実行する必要がある外部の JavaScript または CSS ファイルです。目標は、ページを適切に表示するために必要なコア CSS と JavaScript コードのみを実行することです。

最初のタスクは、ページの読み込み時に実行する必要がないコードを見つけることです。

  1. [レンダリング ブロック リソースの削除] をクリックすると、ブロックしているリソース(lodash.jsjquery.js)が表示されます。

    「レンダリング ブロック リソースを減らす」についての詳細情報。

  2. オペレーティング システムによっては、次のキーを押してコマンド メニューを開きます

    • Mac の場合: command+shift+P
    • Windows、Linux、ChromeOS の場合: Ctrl+Shift+P
  3. Coverage」と入力して [Show Coverage] を選択します。

    Lighthouse パネルからコマンド メニューを開く。

    ドロワー[Coverage] タブが開きます。

    [カバレッジ] タブ。

  4. [再読み込みを行います。 再読み込み] をクリックします。[カバレッジ] タブには、ページの読み込み中に bundle.jsjquery.jslodash.js の各コードが実行されている量の概要が表示されます。

    カバレッジ レポート。

    このスクリーンショットを見ると、jQuery ファイルと Lodash ファイルのそれぞれ約 74% と 30% が使用されていないことがわかります。

  5. jquery.js 行をクリックします。DevTools によって、[ソース] パネルでファイルが開きます。横に緑色のバーがある場合、その行は実行されています。コード行の横に赤いバーが表示されている場合、そのコード行は実行されておらず、ページ読み込み時に必要ないことは明らかです。

    [ソース] パネルに jQuery ファイルを表示しているところ。

  6. jQuery コードを少しスクロールします。「実行される」行の一部は、実際にはコメントだけです。コメントを削除するミニファイアでこのコードを実行すると、このファイルのサイズを縮小できます。

つまり、独自のコードを作成する場合、[カバレッジ] タブを使用すると、コードを 1 行ずつ分析し、ページの読み込みに必要なコードのみを送信できます。

ページを読み込むのに jquery.js ファイルと lodash.js ファイルは必要ですか?[Request Blocking] タブには、リソースが利用できない場合の動作が表示されます。

  1. [ネットワーク] タブをクリックして、コマンド メニューをもう一度開きます
  2. まず「blocking」と入力し、[Show Request Blocking] を選択します。[リクエストのブロック] タブが開きます。

    [リクエストのブロック] タブ。

  3. [[追加] をクリックします。 パターンを追加] をクリックし、テキスト ボックスに「/libs/*」と入力し、Enter キーを押して確定します。

    「libs」ディレクトリへのリクエストをブロックするパターンを追加します。

  4. ページを再読み込みします。jQuery と Lodash のリクエストは赤色です(ブロックされた)。ページは引き続き読み込まれ、インタラクティブであるため、これらのリソースは必要ないようです。

    [ネットワーク] パネルに、リクエストがブロックされたことが表示されます。

  5. 削除 [すべてのパターンを削除] をクリックして、/libs/* のブロック パターンを削除します。

一般に、[Request Blocking] タブは、特定のリソースが利用できない場合のページの動作をシミュレーションするのに役立ちます。

次に、これらのファイルへの参照をコードから削除して、ページを再度監査します。

  1. エディタタブで template.html を開きます。
  2. 対応する <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>
    
  3. サイトの再ビルドと再デプロイが完了するまで待ちます。

  4. [Lighthouse] パネルでページを再度監査します。総合スコアが再び向上したはずです。

    レンダリング ブロック リソースを削除した後の Lighthouse レポート。

現実世界でのクリティカル レンダリング パスの最適化

クリティカル レンダリング パスとは、ページの読み込みに必要なコードを指します。一般的に、ページの読み込み時に重要なコードだけを配布し、それ以外はすべて遅延読み込みすることで、ページの読み込みを高速化できます。

  • 削除できるスクリプトが見つかる可能性はほとんどありませんが、ページ読み込み中にリクエストする必要はなく、代わりに非同期リクエストできるスクリプトが見つかることがよくあります。async または defer の使用をご覧ください。
  • フレームワークを使用している場合は、本番環境モードがあるかどうかを確認します。このモードでは、ツリー シェイキングなどの機能を使用して、重要なレンダリングをブロックしている不要なコードを排除できます。

メインスレッドの作業を軽減

最新のレポートでは、[オポチュニティ] セクションに多少の節約の可能性が示されています。[診断] セクションまでスクロールすると、最大のボトルネックはメインスレッド アクティビティが多すぎるようです。

メインスレッドは、HTML、CSS、JavaScript の解析と実行など、ブラウザがページを表示するために必要なほとんどの作業を行う場所です。

目標は、[パフォーマンス] パネルを使用して、ページの読み込み中にメインスレッドが行っている処理を分析し、不要な処理を延期または削除する方法を見つけることです。

  1. [パフォーマンス] > [設定] の順にタップします。 キャプチャ設定] を開き、[ネットワーク] を [低速 3G] に、[CPU] を [6 倍スローダウン] に設定します。

    [パフォーマンス] パネルでの CPU とネットワーク スロットリングの設定

    通常、モバイル デバイスはノートパソコンやデスクトップ パソコンに比べてハードウェアの制約が強いため、これらの設定では、あたかも性能の低いデバイスを使用しているかのようにページを読み込むことができます。

  2. [再読み込みを行います。 再読み込み] をクリックします。 DevTools がページを再読み込みし、そのページの読み込みに必要なすべての操作を可視化します。この可視化をトレースtraceと呼びます。

    パフォーマンス パネルのページ読み込みのトレース。

トレースには、左から右に時系列でアクティビティが表示されます。上部の FPS、CPU、NET グラフには、フレーム/秒、CPU アクティビティ、ネットワーク アクティビティの概要が表示されます。

トレースの [Overview] セクション。

[Overview] セクションに表示される黄色の壁は、CPU がスクリプト アクティビティで完全にビジー状態であったことを示します。これは、JavaScript の作業を減らしてページの読み込みを高速化できるかどうかを知る手がかりになります。

トレースを調べて、JavaScript の作業を軽減する方法を見つけます。

  1. [速度] セクションをクリックして展開します。

    [タイミング] セクション

    React には多数の User Timing のメジャーがあります。Tony のアプリは React の開発モードを使用しているようです。React の本番環境モードに切り替えると、パフォーマンスを簡単に向上させることができるでしょう。

  2. もう一度 [タイミング] をクリックすると、そのセクションが閉じます。

  3. [Main] セクションを確認します。このセクションには、メインスレッドのアクティビティのログが左から右に時系列で表示されます。Y 軸(上から下)はイベントが発生した理由を示します。

    メイン セクション。

    この例では、Evaluate Script イベントによって (anonymous) 関数が実行され、それによって __webpack__require__ が実行され、それによって ./src/index.jsx が実行されます。

  4. [Main] セクションの一番下までスクロールします。フレームワークを使用する場合、上位アクティビティのほとんどはフレームワークによって発生し、通常はユーザーが制御できません。通常、アプリによるアクティビティは下部に表示されます。

    mineBitcoin アクティビティ

    このアプリでは、App という関数が原因で mineBitcoin 関数が何度も呼び出されているようです。トニーはファンのデバイスを使って暗号通貨をマイニングしていたようです...

  5. 下部の [Bottom-Up] タブを開きます。このタブには、最も時間がかかったアクティビティの内訳が表示されます。[Bottom-Up] セクションに何も表示されない場合は、[Main] セクションのラベルをクリックします。

    [Bottom-Up] タブ。

    [Bottom-Up] セクションには、現在選択されているアクティビティまたはアクティビティのグループに関する情報のみが表示されます。たとえば、mineBitcoin アクティビティの 1 つをクリックすると、[Bottom-Up] セクションにはその 1 つのアクティビティの情報のみが表示されます。

    [セルフ時間] 列には、各アクティビティに直接費やされた時間が表示されます。この場合、メインスレッド時間の約 82% が mineBitcoin 関数に費やされています。

本番環境モードを使用して JavaScript アクティビティを減らすことで、ページの読み込みが速くなるかどうかを確認する時間です。本番環境モードで開始:

  1. エディタタブで webpack.config.js を開きます。
  2. "mode":"development""mode":"production" に変更します。
  3. 新しいビルドがデプロイされるまで待ちます。
  4. ページを再度監査します。

    本番環境モードを使用するように webpack を構成した後の Lighthouse レポート。

mineBitcoin の呼び出しを削除して、JavaScript アクティビティを削減します。

  1. エディタタブで src/App.jsx を開きます。
  2. constructorthis.mineBitcoin(1500) の呼び出しをコメントアウトします。
  3. 新しいビルドがデプロイされるまで待ちます。
  4. ページを再度監査します。

不要な JavaScript 処理を削除した後の Lighthouse レポート。

いつものように、Largest Contentful Paint 指標や Cumulative Layout Shift 指標を減らすなど、やるべきことがまだあります。

現実世界でメインスレッドの処理が減る

一般的に、[パフォーマンス] パネルは、サイトの読み込み時のアクティビティを把握し、不要なアクティビティを削除する方法を見つける最も一般的な方法です。

console.log() に近いアプローチを希望する場合は、User Timing API を使用してアプリのライフサイクルの特定のフェーズを任意にマークアップし、各フェーズの所要時間を追跡できます。

概要

  • サイトの読み込みパフォーマンスの最適化に着手するときには、必ず監査から始めます。監査はベースラインを確立し、改善方法のヒントを提供します。
  • 一度に 1 つの変更を行い、変更のたびにページを監査して、その単独の変更がパフォーマンスに及ぼす影響を確認します。

次のステップ

自分のサイトで監査を実施するレポートの解釈や読み込みのパフォーマンスを改善する方法をお探しの場合は、DevTools コミュニティでさまざまな方法を確認できます。

  • このドキュメントのバグについては、developer.chrome.com リポジトリで報告してください。
  • Chromium Bugs から DevTools でバグレポートを提出します。
  • 機能と変更点については、メーリング リストをご覧ください。サポートに関する質問には、メーリング リストを使用しないでください。代わりに Stack Overflow を使用してください。
  • DevTools の使用方法に関する一般的なヘルプについては、Stack Overflow をご覧ください。バグに関するリクエストを提出する場合は、必ず Chromium バグを使用してください。
  • @ChromeDevTools でツイートします。