適切な圧縮レベルを選択する

ウェブページ上でダウンロード容量の大半を占めるのは画像であることが多く、表示スペースの大部分を占めることもよくあります。その結果、多くの場合、画像を最適化することで、ウェブサイトのバイト数の大幅な削減とパフォーマンスの向上を実現できます。ブラウザがダウンロードする必要があるバイト数が少なければ少ないほど、クライアントの帯域幅に対する競合が少なくなり、ブラウザは有用なコンテンツをダウンロードして画面上にすばやくレンダリングできます。

画像の最適化は芸術であり科学でもあります。個々の画像の最適な圧縮方法に関する決定的な答えがないからこそ芸術であり、画像のサイズを大幅に縮小できるよく開発された手法やアルゴリズムは数多く存在するため、科学です。画像に最適な設定を見つけるには、形式の機能、エンコードされたデータの内容、品質、ピクセルサイズなど、多くの項目について慎重に分析する必要があります。

ベクター画像の最適化

最新のブラウザはすべて、Scalable Vector Graphics(SVG)をサポートしています。SVG は、2 次元グラフィック用の XML ベースの画像形式です。SVG マークアップは、ページに直接埋め込むことも、外部リソースとして埋め込むこともできます。ほとんどのベクターベースの描画ソフトウェアでは SVG ファイルを作成できます。また、任意のテキスト エディタで手作業で直接記述することもできます。

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.2" baseProfile="tiny" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
    x="0px" y="0px" viewBox="0 0 612 792" xml:space="preserve">
<g id="XMLID_1_">
  <g>
    <circle fill="red" stroke="black" stroke-width="2" stroke-miterlimit="10" cx="50" cy="50" r="40"/>
  </g>
</g>
</svg>

上の例では、黒の輪郭と赤の背景を持つ以下の単純な円をレンダリングしています。これは Adobe Illustrator からエクスポートされたものです。

<?xml version="1.0"Encoding="utf-8"?>

おわかりのように、このファイルには、レイヤ情報、コメント、XML 名前空間など、ブラウザでのアセットのレンダリングに不要な場合が多いメタデータが含まれています。そのため、SVGO などのツールを使用して SVG ファイルを圧縮することをおすすめします。

たとえば、SVGO を使用すると、Illustrator で生成された上記の SVG ファイルのサイズが 58% 削減され、470 バイトから 199 バイトに減ります。

<svg version="1.2" baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 612 792"><circle fill="red" stroke="#000" stroke-width="2" stroke-miterlimit="10" cx="50" cy="50" r="40"/></svg>

SVG は XML ベースの形式であるため、GZIP 圧縮を適用して転送サイズを小さくすることもできます。SVG アセットを圧縮するようにサーバーが構成されていることを確認してください。

ラスター画像は、個々の「ピクセル」からなる 2 次元のグリッドです。たとえば、100 x 100 ピクセルの画像は 10,000 ピクセルのシーケンスです。そして、各ピクセルは「RGBA」値、すなわち(R)赤チャンネル、(G)緑チャンネル、(B)青チャンネル、(A)アルファ(透明度)チャンネルを保存します。

内部的には、ブラウザは各チャネルに 256 個の値(シェード)を割り当てます。これは、チャネルあたり 8 ビット(2 ^ 8 = 256)、ピクセルあたり 4 バイト(4 チャネル x 8 ビット = 32 ビット = 4 バイト)に相当します。そのため、グリッドの寸法がわかれば、ファイルサイズを簡単に計算できます。

  • 100x100 ピクセルの画像は 10,000 ピクセルで構成される
  • 10,000 ピクセル x 4 バイト = 40,000 バイト
  • 40,000 バイト ÷ 1,024 = 39 KB
ディメンション ピクセル ファイルサイズ
100 x 100 10,000 39 KB
200×200 40,000 156 KB
300×300 90,000 351 KB
500×500 250,000 977 KB
800×800 64 万 2,500 KB

100 x 100 ピクセルの画像で 39 KB というのは大した問題のようには思えないかもしれませんが、画像が大きいとファイルサイズが急激に増加し、画像アセットのダウンロードに時間がかかり、コストもかかります。この投稿ではこれまで、「非圧縮」の画像形式のみに焦点を当ててきました。幸いなことに、画像ファイルのサイズを小さくする方法はたくさんあります。

シンプルな戦略の一つは、画像の「ビット深度」をチャンネルあたり 8 ビットから小さなカラーパレットに減らすことです。チャンネルあたり 8 ビットの場合、チャンネルあたり 256 個の値、合計 16,777,216 色(256 ^ 3)になります。パレットを 256 色に減らすとどうなるでしょうか。 この場合、RGB チャネルに必要なのは合計で 8 ビットのみで、ピクセルあたり 2 バイトをすぐに節約できます。つまり、元のピクセルあたり 4 バイトの形式と比べて圧縮率が 50% 低下します。

圧縮のアーティファクト
左から右(PNG): 32 ビット(1,600 万色)、7 ビット(128 色)、5 ビット(32 色)。

グラデーションや空など、徐々に色が変化する複雑なシーンでは、5 ビットのアセットで空がピクセル化されるなど、視覚的なアーティファクトが発生しないように、より大きなカラーパレットが必要です。一方、画像に数色しか使用していない場合、パレットを大きくすると貴重な情報が無駄になってしまいます。

個々のピクセルに格納されているデータを最適化したら、さらに巧みに、近傍のピクセルも調べられます。つまり、空やテクスチャの繰り返しなど、類似した色の近傍のピクセルが多数あるため、多くの画像、特に写真には、類似した色のピクセルが多数あることがわかります。この情報を利用して、圧縮器は、デルタ エンコードを適用できます。デルタ エンコードでは、ピクセルごとに個別の値を保存する代わりに、隣接するピクセル間の差分を保存できます。隣接するピクセルが同じ場合、デルタは「ゼロ」であるため、1 ビットだけで保存できます。それだけではありません。

人間の目は色によって感度レベルが異なります。そのため、これらの色のパレットを増減することで、カラー エンコードを最適化できます。「周辺」ピクセルは 2 次元のグリッドを形成します。つまり、各ピクセルには複数の近傍があります。この事実を利用して、デルタ エンコードをさらに改善できます。各ピクセルの最近傍だけを確認する代わりに、隣接する大きなピクセルのブロックを調べ、異なる設定で異なるブロックをエンコードできます。

このように、画像の最適化はすぐに複雑になり(ユーザーの視点によっては楽しい)、学術研究や商業研究が活発に行われている分野です。画像は大量のバイトを占めるため、優れた画像圧縮技術の開発には多くの価値があります。詳しくは、Wikipedia のページをご覧になるか、WebP 圧縮手法に関するホワイトペーパーで実践的な例をご確認ください。

サイトの画像の最適化にどう役立つのか 重要なのは、RGBA ピクセル、ビット深度、さまざまな最適化手法など、問題の形状を理解することです。さまざまなラスター画像形式の説明に入る前に、これらのコンセプトをすべて理解し、念頭に置くことが重要です。

可逆画像圧縮と非可逆画像圧縮

ページのソースコードや実行可能ファイルなど、特定のタイプのデータについては、圧縮ツールによって元の情報が改ざんまたは失われることがないようにすることが重要です。データが 1 つでも欠落しているか間違っていると、ファイルの内容の意味が完全に変わったり、最悪のケースでは、完全に壊れたりする可能性があります。画像、音声、動画など、他の種類のデータについては、元のデータの「近似」表現を提供してもまったく問題ない場合があります。

実際のところ、人間の目の仕組みにより、画像のファイルサイズを小さくするために、各ピクセルに関する情報の一部を破棄することはしばしばです。たとえば、人間の目は色によって感度が異なるため、一部の色をエンコードするためのビット数を減らすことができます。そのため、一般的な画像最適化パイプラインは、次の 2 つの大まかなステップで構成されます。

  1. 画像は、一部のピクセルデータを除外する非可逆フィルタで処理されます。
  2. 画像は、ピクセルデータを圧縮する可逆フィルタで処理されます。

最初のステップは省略可能です。正確なアルゴリズムは特定の画像形式によって異なりますが、どの画像でも非可逆圧縮ステップを実行してサイズを削減できることを理解しておくことが重要です。実際、GIF、PNG、JPEG などのさまざまな画像形式の違いは、非可逆ステップと可逆ステップを適用する際に使用(または省略)する特定のアルゴリズムの組み合わせにあります。

では、非可逆最適化と可逆最適化の「最適」な構成とは何でしょうか。答えは、画像コンテンツと、非可逆圧縮によって生じるファイルサイズとアーティファクト間のトレードオフなど、独自の基準によって異なります。場合によっては、不可逆最適化をスキップして、複雑な詳細を完全な忠実度で伝えることもできます。また、積極的な非可逆最適化を適用して、画像アセットのファイルサイズを縮小できることもあります。 ここで、自身の判断とコンテキストが作用する必要があります。普遍的な設定は 1 つもありません。

実践例として、JPEG などの非可逆形式を使用する場合、圧縮ツールは通常、カスタマイズ可能な「品質」設定(Adobe Photoshop の「ウェブ用に保存」機能で提供される品質スライダーなど)を公開します。これは通常、非可逆アルゴリズムと可逆アルゴリズムの特定のコレクションの内部動作を制御する 1 ~ 100 の数値です。最適な結果を得るには、画像のさまざまな画質設定を試し、恐れずに画質を下げてください。多くの場合、表示結果は非常に良好で、ファイルサイズを大幅に削減できます。

Core Web Vitals に対する画像圧縮の影響

画像は Largest Contentful Paint の候補になることが多いため、画像のリソース読み込み時間を短縮することで、ラボ現場の両方で LCP を改善できます。

ラスター画像形式で圧縮設定を試す場合は、WebP 形式と AVIF 形式を試して、古い形式と比較して同じ画像を小さなフットプリントで提供できるか確認するようにしてください。

ただし、ラスター画像を過圧縮しないように注意してください。最適なソリューションは、画像最適化 CDN を使用して最適な圧縮設定を見つけることですが、Butteraugli などのツールを使用して視覚的な違いを推定することもできるでしょう。これにより、画像を過度にエンコードして品質を落とすことがなくなります。

画像最適化チェックリスト

画像の最適化に取り組む際は、次のヒントとテクニックを参考にしてください。

  • ベクター形式を選ぶ: ベクター画像は解像度やスケールに依存しないため、マルチデバイスや高解像度の世界に最適です。
  • SVG アセットを最小化して圧縮する: ほとんどの描画アプリケーションで生成される XML マークアップには、削除できる不要なメタデータが含まれていることがよくあります。SVG アセットに GZIP 圧縮を適用するようにサーバーを設定してください。
  • 古いラスター形式よりも WebP または AVIF を優先する: WebPAVIF 画像は通常、古い画像形式よりもはるかに小さくなります。
  • 最適なラスター画像形式を選択する: 機能要件を判断し、各アセットに適した形式を選択します。
  • ラスター形式の最適な品質設定をテストする: ためらわずに「品質」設定を減らしてください。多くの場合、非常に良い結果が得られ、バイト数も大幅に削減されます。
  • 不要な画像メタデータを削除する: 多くのラスター画像には、アセットに関する不要なメタデータ(位置情報、カメラ情報など)が含まれています。適切なツールを使用してこのデータを削除します。
  • 拡大縮小された画像を提供する: 画像のサイズを変更し、「表示」サイズを画像の「自然な」サイズにできるだけ近づけます。 特に、サイズの大きい画像はサイズ変更時のオーバーヘッドの最大の原因となるため、細心の注意を払ってください。
  • 自動化、自動化、自動化: すべての画像アセットが常に最適化されるように、自動化ツールとインフラストラクチャに投資します。