Base64画像:便利な罠か、それとも使える道具か?
画像をBase64文字列として埋め込むのは便利に見えます。役立つ場面と害になる場面を解説します。
画像をHTMLやCSSに直接埋め込めます。別ファイル不要。追加のHTTPリクエストも不要。
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA..." />
便利です。でも、すぐには分からないコストもあります。
仕組み
Base64はバイナリデータをASCIIテキストとしてエンコードします。あらゆる画像がコピペ可能な文字列になります。
その文字列は元のファイルより約33%大きくなります。30KBの画像は40KBの文字列になります。
Base64が役立つ場面
小さなアイコン。 200バイトのアイコンをBase64にすれば、HTTPリクエストを1つ節約できます。HTTP/2でこれの重要性は下がりましたが、非常に小さな画像では今でも有効です。
メールHTML。 メールクライアントは外部画像をブロックします。埋め込み画像なら「画像を読み込む」プロンプトなしで表示されます。
単一ファイル配布。 オフラインで動くHTMLを共有する場合。すべてが1つのファイルに。
CSS内のデータURI。 スタイルシートに埋め込まれた背景画像。HTTPリクエストは減りますが、CSSファイルは大きくなります。
Base64が害になる場面
大きな画像。 33%のサイズ増加が積み重なります。100KBの画像が133KBのテキストになります。
キャッシング。 外部画像は個別にキャッシュされます。Base64画像はHTML/CSSの一部——ページが変わると全体がリロードされます。
パース時間。 ブラウザはレンダリング前にBase64をデコードしなければなりません。バイナリファイルを直接読み込むより処理が必要です。
メンテナンス。 埋め込み画像を更新するにはコードを編集する必要があります。外部ファイルの更新の方がシンプルです。
HTTP/2の要因
HTTP/1.1は接続オーバーヘッドが高コストでした。複数の小さな画像は複数の遅いリクエストを意味しました。
HTTP/2はリクエストを効率的に多重化します。「HTTPリクエストを節約」という論拠は今では弱くなっています。
サーバーがHTTP/2をサポートしているなら(ほとんどがそうです)、外部画像の方が通常は良いです。
実践的なガイドライン
1KB未満: Base64を検討しましょう。オーバーヘッドは最小限です。
1-10KB: ケースバイケースで評価しましょう。重要なアイコンは恩恵を受けるかもしれませんが、装飾画像はおそらく受けません。
10KB以上: 外部ファイルを使いましょう。サイズペナルティに見合いません。
頻繁に更新される: 外部ファイル。画像更新のためにコードを変更するのは避けましょう。
複数ページで共有: 外部ファイル。キャッシングが複数のページ読み込みで恩恵をもたらします。
パフォーマンステスト
推測しないでください。テストしましょう。
Base64埋め込みありとなしでページ全体のサイズを比較します。実際の読み込み時間を測定します。
「正しい」答えは具体的な状況によります——画像サイズ、キャッシング戦略、HTTPバージョン、更新頻度。
代替手段
スプライトシート。 小さなアイコンを1つの画像にまとめ、CSSで部分を表示。1回のリクエスト、通常のキャッシング。
アイコンフォント。 ベクターアイコンをフォントとして。拡大縮小可能、CSSでスタイル設定可能。
インラインSVG。 ベクターグラフィックスなら、インラインSVGの方がBase64 PNGより柔軟です。
Base64画像はファイルサイズと引き換えに便利さを得ます。このトレードオフが意味を持つのは、非常に小さな画像か、メールのような特殊なケースだけです。ほとんどのWeb用途では、外部ファイルの方がパフォーマンスが良いです。