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

多くの場合、画像はウェブページでダウンロードされるデータ容量の大部分を占め、表示スペースの大部分を占めます。その結果、画像を最適化することで、ウェブサイトのバイト削減とパフォーマンスの改善が最大限に見込めることがよくあります。ブラウザでダウンロードする必要があるバイト数が小さいほど、クライアントの帯域幅の競争が激しくなり、ブラウザが有用なコンテンツをダウンロードして画面に表示するまでの時間が短くなります。

画像の最適化は、芸術であり科学でもあります。個々の画像の最適な圧縮方法に決定的な答えがないため芸術で、画像のサイズを大幅に縮小できる技術やアルゴリズムが数多く開発されているため科学でもあります。画像の最適な設定を見つけるには、形式の機能、エンコードされたデータのコンテンツ、品質、ピクセル寸法など、多くのディメンションに沿って慎重に分析する必要があります。

ベクター画像の最適化

最新のブラウザはすべて、2 次元グラフィック用の XML ベースの画像形式である Scalable Vector Graphics(SVG)をサポートしています。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 次元のグリッドです。たとえば、100x100 ピクセルの画像は 10,000 ピクセルのシーケンスです。次に、各ピクセルには「RGBA」値、すなわち(R)赤チャンネル、(G)緑チャンネル、(B)青チャンネル、(A)アルファ(透明度)チャンネルが格納されます。

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

  • 100×100 ピクセルの画像は 10,000 ピクセルで構成されています。
  • 10,000 ピクセル x 4 バイト = 40,000 バイト
  • 40,000 バイト / 1024 = 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 は大したことではないと思われるかもしれませんが、大きな画像ではファイルサイズがすぐに増大し、画像アセットのダウンロードに時間がかかり、コストが高くなります。この投稿では、これまでのところ、「非圧縮」画像形式のみに焦点を当ててきました。幸いなことに、画像ファイルのサイズを小さくするにはさまざまなことができます。

シンプルな戦略の 1 つは、画像の「ビット深度」をチャンネルあたり 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 つのデータが欠落しているか、1 つでも誤りがあると、ファイルの内容が完全に変わってしまうか、最悪の場合、データが壊れてしまう可能性があります。画像、音声、動画など、その他の一部のデータタイプについては、元のデータの「概算」表現を提供してもまったく許容されない場合があります。

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

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

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

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

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

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

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

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

ただし、ラスター画像を過度に圧縮しないように注意してください。この解決策としては、画像最適化 CDN を使用して最適な圧縮設定を見つける方法がありますが、代わりに Butteraugli などのツールを使用して見た目の違いを推定するという方法もあります。これにより、画像のエンコード頻度が高すぎて画質が過度に低下することがなくなります。

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

画像の最適化に取り組む際に役立つヒントとテクニックをご紹介します。

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