Data URI化した画像とその再利用性

Data URI化した画像はHTTPリクエストの削減に大いに役に立つので積極的に使って良いと思う。けど、CSSにおいて変数が使えないことなどの理由からその再利用性は低いため、注意して書かないと同じData URI化した画像がいくつもCSSに出てくるなどという無駄につながりかねない。極端な例では3KBくらいのData URI化した同じ画像が8–10以上出てくるCSSファイルとか見たことが何回もある。

単なるアイコンなどは使い回しすることはあまりなく、クラス名に紐付けられるだけなのでこういう問題は起こらないけど、上記のような透過させたグラデーションのような使い回すことを意図したテクスチャを違う背景色と混ぜてアレンジするというような使い方においてData URIを利用すると重複が起こりやすい。そういう時にはOOCSS的なアプローチでData URI化した画像を使うためだけのクラスを作ってセレクターを独立させてやるとか一工夫が必要になる。Sassでは@extendが活躍する。

CSSプリプロセッサーでの利用

CSSプリプロセッサーでは変数を定義できることが多く、それを利用するとData URIを比較的カジュアルに扱える。その結果としてこの重複する問題が特に表面化しづらい。例えば@extendではなく@mixinでData URI化した画像を利用していたりすれば、SCSSのコードとしては一回しか出てこないにも関わらず生成されたCSSには何回も出てくるなどということは普通に有り得る。CompassではData URI化する関数とかも用意されているので便利な半面、更に表面化しづらそう。

まぁこれはData URI化した画像を使う時に限った話ではなく、CSSプリプロセッサーの使用において生成されるCSSを強く意識して書く必要があるということに過ぎないんだけど。中でもSassは単なる便利ツールではなくなりつつあり、SCSSのコードと生成されるCSSのコードが乖離しやすいのでより重要。あんまりCSSから離れたくないとかそういう理由でLESSを選ぶのも悪くない気がする。

CSS Variablesではどうなる?

CSSプリプロセッサーの変数では解決されないけど、CSS Variablesが多くのブラウザーで使えるようになると解決されるはず。

:root {
  var-subtle-noise-texture: url("data:image/png;base64,iVBORw0KGgoAAAAN...");
}

.foo {
  background-color: #fffcf0;
  background-image: var(subtle-noise-texture);
}

.bar {
  background-color: #edeade;
  background-image: var(subtle-noise-texture);
}

試せないので試してないけど……。


今までCSSでurl()で参照していたものを単純にData URI化しちゃえばHTTPリクエストが減って快適になりやすいけど、HTTPリクエストを減らせばファイルサイズ大きくなっても良いわけではないってわけではない。もちろんHTTPリクエストの削減の方が優先度は高いけど。

Data URI化した画像を大量に含んで肥大化したCSSファイルはキャッシングという面での再利用性に問題がある……というのは過去の問題だと思うので、多分無視して良い(要出典)。


Data URI化するにはどんなやり方でも良いと思うんだけど、ローカルでサクッとできる何かを持ってると機械的に処理できるようになるので生産性が上がる。僕は自分で書いたPerlスクリプトで誤魔化してる。pngcrushなんかを公開しているPNG and MNG toolsでbase64やuuencodeを利用したPng2uriというシェルスクリプトが最近公開されてたり、探せば色々あると思うので1つくらいはローカルに何か用意しておくべき。