「Data URI」で画像のHTTPリクエストを削減

「Data URI」で画像のHTTPリクエストを削減

「Data URI」って何ぞやと思う人も多いと思いますが、説明するより見てもらった方が早いです。
下記の画像をご覧ください。

なんということないゴミ箱アイコンですが、クリックしたあとのURIをご覧ください。
アップされた画像ファイルを参照しているわけではなく、コード自体で画像が生成されています。

ここに貼り付けている画像のsrcも下記コードで構成されています。

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADoAAAA6CAMAAADWZboaAAAAflBMVEX///8nJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJydISEhKSkpJSUlNTU1SUlJHR0c0NDROTk5CQkI+Pj5AQEBPT082NjY9PT1ERERGRkZTU1NFRUU/Pz9DQ0NBQUEFOc4RAAAAFHRSTlMAAPz2lhVjTtK9+RurV64q7efz8D8SYyAAAAC4SURBVHhe7c5XC8IwGIXhdO+hZnS71///g9LvQlD7pREJSMlzeeCFQ/QzjMChwAksoF5mMT8DHmffpb7NOAOc2b5S6rkhHR04lNDyA0yh60nTqN+NL+tKNE+iqsdt10fS1O4EayYx0dnSlEKIxFSeShE11hsYtaU/3KU1QiE9IfSmF8QS0yPib9MbYolpj3hJTXpHLDDdXKfL7Xo2zffbSft8Ni3KdvgMh7YsyKwkXdEPqzQh+hjGAwiobsMAdu8gAAAAAElFTkSuQmCC

本来バイナリデータである画像などをURIとしてアクセスできる形に変換したものが「Data URI」と呼ばれています。

上記例のゴミ箱画像はモバイル版Gmailで使われているアイコン画像で、Googleのモバイルサービスでは Data URI での参照が多用されています。

メリット

HTTPリクエストが減らせる
外部に置かれた画像でなく、このコード自体で画像が生成されているのでHTTPリクエスト扱いになりません。

CSSスプライトより一歩上
HTTPリクエスト対策のCSSスプライトでも最低1個はHTTPリクエストがかさみますが、全対応した場合はゼロにできます。CSSスプライトはスマホ対応がかなり面倒で扱いにくいですが、Data URI で読みこめば1個1個切り分けた画像と同じ扱いで使えます。

デメリット

バイナリデータよりサイズが増す
3割ほどサイズが増すようですが、アイコン程度の小さい画像であればHTTPリクエスト数を1件減らす方がメリット大きいです。大きい画像はその分サイズも増すので向いていません。

IE7以前で使えない
IE7をサポートしなければデメリットになりませんが、古くからのユーザを持つサービスは注意が必要です。
※GoogleもPC表示では従来のCSSスプライトを利用しています。

デザイナーの負担増
画像の変換の必要があり、ファイル名が分からなくなり、かつコード量が増えるのでメンテナンス性が下がります。

便利ツール

画像を直接 Data URI に変換してくれるサービスもあります。
http://blog.thingslabo.com/archives/000058.html

また下記のようにコーディングの時点ではローカルのファイルを使い、サーバサイドで Data URI に処理する手法もあるようです。
http://qiita.com/items/3134467210e0022f4a02

現実的にデザイナーが使っていくために

ファイル名は見えないわコードは荒れるわで、HTML内で直接 Data URI を扱おうとすると結構負担が増します。上記のようにサーバサイドで対応する方法もあるようですが、ノンプログラマー・デザイナーには敷居が高く環境にも依存するので、CSSで一元管理するのが楽だと思います。

.img_create {
	width:**;
	height:**;
	background-image:data:image/png;base64,~;
}
.img_delete {
	width:**;
	height:**;
	background-image:data:image/png;base64,~;
}
i[class^="img_"] {
	display:inline-block;
	background-repeat:no-repeat;
}

上記はあくまで一例ですが、「img_」など画像と分かりやすいクラスで統一すると良いです。

<i class="img_create"></i>

それで上記のように呼び出す。
端的に言ってしまえばCSSスプライトを作るのと同じです。

普通に画像を使うより結構な手間がかかりますが、UIに使う汎用的な画像なら一度作れば後は楽ですし、究極的に表示速度を早くする手法としては試す価値があると思います。

筆者について

KaBuKi
ゲームとジョジョを愛するファミッ子世代。好きな言葉は「機能美」。
公私ともにWebサービスを作る系男子。