不要なリソースのダウンロードを排除することに加え、ページの読み込み速度を改善するためにできることとして、残りのリソースを最適化して圧縮し、全体的なダウンロード サイズを最小限に抑えることが挙げられます。
データ圧縮の基本
未使用のリソースのダウンロードを回避するようにウェブサイトを設定したら、次は、ブラウザがダウンロードする必要がある残りの対象リソースを圧縮します。リソースの種類(テキスト、画像、フォントなど)に応じて、ウェブサーバーで有効にできる汎用ツール、特定のコンテンツ タイプ向けの前処理最適化、デベロッパーからの入力を必要とするリソース固有の最適化など、さまざまな手法から選択できます。
最適なパフォーマンスを実現するには、次のすべての手法を組み合わせる必要があります。
- 圧縮とは、より少ないビット数で情報をエンコードするプロセスです。
- 不要なデータを除外すると、常に最良の結果が得られます。
- 圧縮手法とアルゴリズムにはさまざまなものがあります。
- 最適な圧縮を実現するには、さまざまな手法が必要です。
データのサイズを小さくするプロセスをデータ圧縮といいます。多くの人が、圧縮率、圧縮速度、さまざまな圧縮アルゴリズムで必要なメモリを改善するために、アルゴリズム、手法、最適化を貢献しています。
データ圧縮の詳細な説明は、このガイドの範囲外です。ただし、圧縮の仕組みと、ページに必要なさまざまなアセットのサイズを削減するために使用できる手法を大まかに理解しておくことが重要です。
これらの手法のコアとなる原則を説明するために、この例専用に作成されたシンプルなテキスト メッセージ形式を最適化するプロセスについて考えてみましょう。
# Below is a secret message, which consists of a set of headers in
# key-value format followed by a newline and the encrypted message.
format: secret-cipher
date: 08/25/16
AAAZZBBBBEEEMMM EEETTTAAA
- メッセージには任意のアノテーション(コメントと呼ばれることもあります)を含めることができます。アノテーションは「#」接頭辞で示されます。アノテーションは、メッセージの意味や動作には影響しません。
- メッセージにはヘッダーが含まれる場合があります。ヘッダーは、メッセージの先頭に表示される Key-Value ペア(上記の例では
":"
で区切られています)です。 - メッセージはテキスト ペイロードを運ぶ。
200 文字から始まる前回のメッセージのサイズを小さくするにはどうすればよいですか?
- コメントは興味深いものの、メッセージの意味には影響しません。メッセージを送信するときに除去します。
- ヘッダーを効率的にエンコードする優れた手法があります。たとえば、すべてのメッセージに「format」と「date」があることがわかっている場合は、それらを短い整数 ID に変換して送信できます。ただし、そうではない可能性もあるため、今のところはそのままにしておくことをお勧めします。
- ペイロードはテキストのみです。実際の内容は不明ですが(
"secret-cipher"
を使用しているようです)、テキストを見ただけでも、冗長性が非常に高いことがわかります。繰り返しの文字を送信する代わりに、繰り返しの文字の数をカウントして、より効率的にエンコードすることもできます。たとえば、"AAA"
は"3A"
になり、3 つの A のシーケンスを表します。
これらの手法を組み合わせると、次のような結果が得られます。
format: secret-cipher
date: 08/25/16
3A2Z4B3E3M 3E3T3A
新しいメッセージの長さは 56 文字です。つまり、元のメッセージを 72% 圧縮したことになります。大幅な削減です。
これは、圧縮アルゴリズムがテキストベースのリソースの転送サイズを効果的に削減する方法を示したサンプルです。実際には、圧縮アルゴリズムは前述の例よりもはるかに高度です。ウェブでは、圧縮アルゴリズムを使用してリソースのダウンロード時間を大幅に短縮できます。テキストベースのアセットに圧縮を適用すると、ウェブページでリソースの読み込みにかかる時間が短縮されるため、圧縮なしの場合よりもユーザーがリソースの効果を早く確認できるようになります。
圧縮: 前処理とコンテキスト固有の最適化
ここで説明する最初の手法は圧縮です。圧縮は厳密には圧縮アルゴリズムではありませんが、ソースコードで使用される不要な冗長な文字を削除して、リソースを人間が読みやすくする方法です。ただし、本番環境のウェブサイトでソースコードの機能を維持するために、その読みやすさは必要ありません。また、ウェブ上のリソースの読み込みが遅れる可能性があります。
圧縮は、配信されるリソースのサイズを大幅に削減できるコンテンツ固有の最適化の一種です。この最適化は、ビルドとデプロイのプロセスの一部として適用するのが最適です。たとえば、バンドルは、新しい本番環境コードをウェブサイトにデプロイする直前にリソースを自動的に圧縮できる、よく使用されるソフトウェアの一種です。
重複するデータや不要なデータを圧縮する最善の方法は、削除することです。ただし、任意のデータを削除することはできません。ただし、データ形式とそのプロパティに関するコンテンツ固有の知識があるコンテキストでは、ペイロードの実際の意味や機能に影響を与えることなく、ペイロードのサイズを大幅に削減できます。
<html>
<head>
<style>
/* awesome-container is only used on the landing page */
.awesome-container {
font-size: 120%;
}
.awesome-container {
width: 50%;
}
</style>
</head>
<body>
<!-- awesome container content: START -->
<div>
This is my awesome container, and it is <em>so</em> awesome.
</div>
<!-- awesome container content: END -->
<script>
awesomeAnalytics(); // Beacon conversion metrics
</script>
</body>
</html>
前の HTML スニペットと、それに含まれる 3 つの異なるコンテンツ タイプについて考えてみましょう。
- HTML マークアップ。
- ページの表示をカスタマイズするための CSS。
- JavaScript: インタラクションやその他の高度なページ機能を実現します。
これらのコンテンツ タイプにはそれぞれ、有効なコンテンツの構成要素、コメントの指定方法などに関する異なるルールがあります。ただし、残る問題は「このページのサイズを小さくするにはどうすればよいか」です。
- コードコメントはデベロッパーの強い味方ですが、ブラウザには必要ありません。CSS(
/* ... */
)、HTML(<!-- ... -->
)、JavaScript(// ...
)のコメントを削除すると、ページとそのサブリソースの合計転送サイズが削減されます。 - 「スマート」な CSS 圧縮ツールは、
.awesome-container
のルールを定義する方法が非効率的であることを認識し、他のスタイルに影響を与えることなく 2 つの宣言を 1 つに統合して、より多くのバイト数を節約できます。大量の CSS ルールでこのような冗長性を削除すると、削減効果は大きくなりますが、セレクタはメディアクエリ内など、異なるコンテキストで重複することが多く、積極的に適用できるものではありません。 - スペースとタブは、HTML、CSS、JavaScript でデベロッパーが便利に使用できるものです。追加の圧縮ツールを使用すると、タブとスペースがすべて削除される可能性があります。他の重複除去手法とは異なり、この種の最適化は、ページの表示にスペースやタブが不要であれば、かなり積極的に適用できます。たとえば、HTML ドキュメント内のテキストの行内のスペースは、ユーザーが実際に表示するコンテンツの読みやすさを確保するために保持する必要があります。
<html><head><style>.awesome-container{font-size:120%;width:50%}</style></head><body><div>This is my awesome container, and it is <em>so</em> awesome.</div><script>awesomeAnalytics()</script></body></html>
上記の手順を適用すると、ページの文字数は 516 文字から 204 文字に減り、約 60% の削減となります。読みづらいのは確かですが、使用に支障はありません。最新の開発手法では、適切にフォーマットされ読みやすいバージョンのソースコードを、本番環境に配布する適切に最適化されたコードとは別に保持することもできます。変換された本番環境コードを読み取り可能な形式で提供し、本番環境のバグを簡単にトラブルシューティングできるソースマップと組み合わせることで、ユーザー エクスペリエンスのためにパフォーマンスを最適化しながら、優れたデベロッパー エクスペリエンスを実現できます。
前述の例は、重要なポイントを示しています。汎用圧縮ツール(任意のテキストを圧縮するように設計されたものなど)は、前述の例のページをかなり効果的に圧縮できますが、コメントの削除、CSS ルールの圧縮、その他のコンテンツ固有の最適化を実行することはできません。そのため、前処理、圧縮、その他のコンテキスト対応の最適化が重要になります。
同様に、上記の方法はテキストベースのアセット以外にも拡張できます。画像、動画、その他のコンテンツ タイプには、それぞれ独自の形式のメタデータとさまざまなペイロードが含まれています。たとえば、カメラで写真を撮影すると、通常、そのファイルにはカメラの設定や位置情報など、多くの追加情報が埋め込まれます。このデータは、アプリケーションによっては重要(写真共有サイトなど)である場合もあれば、まったく役に立たないこともあります。削除する価値があるかどうかを検討する必要があります。実際には、このメタデータによって画像ごとに最大数十キロバイト増加する可能性があります。
つまり、アセットの効率を最適化する最初のステップとして、さまざまなコンテンツ タイプのインベントリを作成し、サイズを削減するために適用できるコンテンツ固有の最適化方法を検討します。次に、最適化の対象を特定したら、ビルドとリリースのステップに追加して自動化し、本番環境への新しいリリースごとに一貫して最適化が適用されるようにします。
圧縮アルゴリズムによるテキスト圧縮
テキストベースのアセットのサイズを削減する次のステップは、圧縮アルゴリズムを適用することです。さらに、テキストベースのペイロードで繰り返しパターンを積極的に検索し、ユーザーに送信する前に圧縮を解除し、ユーザーのブラウザに到達した後に圧縮を解除します。その結果、これらのリソースがさらに大幅に削減され、ダウンロード時間が短縮されます。
- gzip と Brotli は、テキストベースのアセット(CSS、JavaScript、HTML)で最適なパフォーマンスを発揮する、よく使用される圧縮アルゴリズムです。
- 最新のブラウザはすべて gzip 圧縮と Brotli 圧縮をサポートしており、
Accept-Encoding
HTTP リクエスト ヘッダーで両方のサポートをアドバタイズします。 - 圧縮を有効にするようにサーバーが構成されている必要があります。ウェブサーバー ソフトウェアでは、多くの場合、テキストベースのリソースを圧縮するモジュールがデフォルトで有効になっています。
- gzip と Brotli の両方を微調整して、圧縮レベルを調整することで圧縮率を改善できます。gzip の場合、圧縮設定は 1 ~ 9 の範囲で、9 が最適です。Brotli の場合、この範囲は 0 ~ 11 で、11 が最適です。ただし、圧縮設定が高いほど時間がかかります。動的に圧縮されるリソース(リクエスト時に圧縮されるリソース)の場合、範囲の中央の設定が、圧縮率と速度の間で最適なトレードオフを提供します。ただし、静的圧縮は可能です。これは、レスポンスが事前に圧縮されるため、各圧縮アルゴリズムで使用可能な最も積極的な圧縮設定を使用できます。
- コンテンツ配信ネットワーク(CDN)は、通常、対象となるリソースの自動圧縮を提供します。CDN は動的圧縮と静的圧縮も管理できるため、圧縮に関する心配が減ります。
gzip と Brotli は、任意のバイト ストリームに適用できる一般的な圧縮ツールです。内部的には、以前に検査したファイルの一部の内容を記憶し、その後、重複するデータ フラグメントを効率的に検出して置き換えようとします。
実際には、gzip と Brotli の両方がテキストベースのコンテンツで最適なパフォーマンスを発揮し、大規模なファイルでは 70 ~ 90% という高い圧縮率を達成することがよくあります。ただし、ロスレスまたはロスのある圧縮手法を使用するほとんどの画像形式など、別のアルゴリズムを使用してすでに圧縮されているアセットに対してこれらのアルゴリズムを実行しても、改善はほとんどまたはまったくありません。
最新のブラウザはすべて、Accept-Encoding
HTTP リクエスト ヘッダーで gzip と Brotli のサポートをアドバタイズします。ただし、クライアントがリクエストしたときに圧縮されたリソースを提供するようにウェブサーバーが正しく構成されていることを確認するのは、ホスティング プロバイダの責任です。
ファイル | アルゴリズム | 非圧縮サイズ | 圧縮後のサイズ | 圧縮比 |
---|---|---|---|---|
angular-1.8.3.js | Brotli | 1,346 KiB | 256 KiB | 81% |
angular-1.8.3.js | gzip | 1,346 KiB | 329 KiB | 76% |
angular-1.8.3.min.js | Brotli | 173 KiB | 53 KiB | 69% |
angular-1.8.3.min.js | gzip | 173 KiB | 60 KiB | 65% |
jquery-3.7.1.js | Brotli | 302 KiB | 69 KiB | 77% |
jquery-3.7.1.js | gzip | 302 KiB | 83 KiB | 73% |
jquery-3.7.1.min.js | Brotli | 85 KiB | 27 KiB | 68% |
jquery-3.7.1.min.js | gzip | 85 KiB | 30 KiB | 65% |
lodash-4.17.21.js | Brotli | 531 KiB | 73 KiB | 86% |
lodash-4.17.21.js | gzip | 531 KiB | 94 KiB | 82% |
lodash-4.17.21.min.js | Brotli | 71 KiB | 23 KiB | 68% |
lodash-4.17.21.min.js | gzip | 71 KiB | 25 KiB | 65% |
上の表は、Brotli と gzip の両方の圧縮で、いくつかのよく知られた JavaScript ライブラリで得られる節約量を示しています。ファイルとアルゴリズムによって、節約率は 65% ~ 86% になります。なお、Brotli と gzip の両方で、各ファイルに最大圧縮レベルが適用されています。可能であれば、gzip ではなく Brotli を優先します。
圧縮を有効にすることは、実装が最も簡単で効果的な最適化の 1 つです。ウェブサイトでこの機能を活用していない場合は、ユーザーのパフォーマンスを改善する大きな機会を逃しています。幸い、多くのウェブサーバーは、この重要な最適化を可能にするデフォルト構成を提供しています。特に CDN は、圧縮速度と圧縮率のバランスをとった方法で実装するのに非常に効果的です。
圧縮がどのように機能しているかを簡単に確認するには、Chrome DevTools を開き、[ネットワーク] ペインを開き、任意のページを読み込んで、ネットワーク ペインの一番下を確認します。

上の画像のように、次のような内訳が表示されます。
- リクエスト数(ページに読み込まれたリソースの数)。
- すべてのリクエストの転送サイズ。これは、ページのリソースに適用された圧縮の効果を表します。
- すべてのリクエストのリソースサイズ。これは、ページのリソースが解凍された後のサイズを示します。
Core Web Vitals への影響
パフォーマンスの改善を測定するには、その改善を反映する指標が必要です。Core Web Vitals イニシアチブは、実際のユーザー エクスペリエンスを反映する指標を作成して認識を高めることを目的としています。これは、単純なページ読み込み時間などの指標とは対照的です。これらの指標は、ユーザー エクスペリエンスの質に明確に結び付けられません。
このガイドで説明する最適化をウェブサイトのリソースに適用した場合、Core Web Vitals への影響は、最適化されたリソースと関連する指標によって異なります。ただし、これらの最適化を適用することでウェブサイトの Core Web Vitals を改善できる場合があります。
- 圧縮された HTML リソースは、その HTML の読み込みとサブリソースの検出を改善し、読み込みを改善できます。これは、ページの Largest Contentful Paint(LCP)に役立ちます。
rel="preload"
などのリソースヒントを使用してリソースの検出可能性に影響を与えることはできますが、リソースヒントを使いすぎると、帯域幅の競合が発生する可能性があります。ナビゲーション リクエストの HTML レスポンスが圧縮されていることを確認することで、プリロード スキャナがその中のリソースをできるだけ早く検出できます。 - 一部の LCP 候補は、圧縮を使用してより早く読み込むこともできます。たとえば、LCP の候補となる SVG 画像は、テキストベースの圧縮によってリソースの読み込み時間を短縮できます。これは、JPEG 画像で不可逆圧縮を使用するなど、他の圧縮方法で本質的に圧縮される他の画像タイプに対して行う最適化とは異なります。
- また、テキストノードも LCP の候補になります。このガイドで説明する手法は、ウェブページのテキストにウェブフォントを使用しているかどうかによって異なります。ウェブフォントを使用している場合は、ウェブフォント最適化のベスト プラクティスが適用されます。ただし、ウェブフォントではなく、リソースの読み込み時間が発生することなく表示されるシステムフォントを使用している場合は、CSS を圧縮して圧縮することでこの時間が短縮され、LCP テキスト ノードのレンダリングがより早く行われるようになります。
まとめ
テキストベースのアセットのエンコードと転送を最適化する方法は、ベースラインのパフォーマンスのコンセプトですが、大きな影響があります。圧縮と圧縮の対象となるリソースがこれらの最適化のメリットを享受できるように、可能な限りのことを行ってください。
さらに重要なのは、これらのプロセスが自動化されていることです。圧縮するには、バンドラを使用して、対象リソースに圧縮を適用します。ウェブサーバーの構成で圧縮がサポートされていることを確認します。また、利用可能な最も効果的な圧縮を使用します。これをできるだけ簡単なものにするには、CDN を使用して圧縮を自動化します。CDN はリソースを圧縮できるだけでなく、非常に高速に圧縮できます。
これらのベースライン パフォーマンスのコンセプトをウェブサイトのアーキテクチャに組み込むことで、パフォーマンスの最適化が確実に行われるようにし、その後の最適化を優れたベースライン プラクティスの堅固な基盤の上に構築できるようにします。