4. PNG画像をBase64エンコードしてみる
試しに150px*150pxのPNG画像を、Base64エンコードしてみましょう。ちなみにこの画像のファイルサイズは1,817バイトです。
このサンプル画像を実際に変換してみると、こんなに長い文字列になります。
data:image/png;base64,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
サンプル画像を変換してみるとデータサイズは2,447バイトになりました。
Base64でエンコードすると、元データと比べデータサイズは約137%となっています。この137%という増加率は変換時の論理から導き出せる数字です。
データサイズが大きくなるということは、元々データサイズの大きな写真などには向きません。ロゴやアイコンなどデータサイズの小さなものに利用するのが良いでしょう。
5. data URI schemeに対応しているブラウザ
モダンなブラウザであればどのブラウザにも対応していますが、残念ながら古いバージョンのInternet Explorer(IE6/IE7)には対応していません。
また、IE8では埋め込むことができるデータサイズに32KBまでという制限があります。さらに、IE8/IE9 共に画像形式(GIF/JPEG/PNG )しか利用できないという制約があります。うっかり忘れていると思わぬバグに繋がるので注意しましょう。
Chrome | Firefox | Safari |
Mobile Safari (iOS6) |
Mobaile Safari (iOS5) |
Mobile Safari (iOS4) |
IE10 | IE9 | IE8 | IE7 | IE6 |
---|---|---|---|---|---|---|---|---|---|---|
○ | ○ | ○ | ○ | ○ | ○ | ○ | △ | △ | × | × |
- CSSの背景画像でインラインイメージを利用する場合、エンコードされた文字列には改行は含めてはいけない(Firefox 5/Google Chrome 17/IE9で問題がおこるため)。
- SVGを埋め込む場合はブラウザがSVGをサポートしているかチェックが必要です。
インラインイメージの使い方
インラインイメージはHTMLのイメージタグ(img)のsrc属性、CSSのbackgroundプロパティ(url)に指定できます。
それぞれのサンプルコードを掲載しておきます(長くなってしまうためデータ部分は省略しています)。
1. HTMLに埋め込んだ場合のサンプルコード
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAACWCAIAAACzY+a1AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAACS9JREFUeNrsmQtsU+cVx+PYzrWdOHHzNnEzSAiQUPFQgFKSkarQMjZaWsHGQ2Rs6li6qRVtVyH1MabSqpOqKWJbppa2bENFfVdjtLRkjJagphQKJUlDQpIRICRxXn4ksWM7fu1cf+ZyuUluQhO7dPv/dGV9+fzdG9s/n++cc63oWV8aExnUL3MRunJ..." />
2. CSSに埋め込んだ場合のサンプルコード
div { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAACWCAIAAACzY+a1AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAACS9JREFUeNrsmQtsU+cVx+PYzrWdOHHzNnEzSAiQUPFQgFKSkarQMjZaWsHGQ2Rs6li6qRVtVyH1MabSqpOqKWJbppa2bENFfVdjtLRkjJagphQKJUlDQpIRICRxXn4ksWM7fu1cf+ZyuUluQhO7dPv/dGV9+fzdG9s/n++cc63oWV8aExnUL3MRunJ5..."); }
パフォーマンスの計測
インラインイメージを使うことでどの程度表示に影響するのか、2つのポイントをチェックしてパフォーマンスを計測してみます。
1つ目はDOMContentLoaded Event(DOMの構築が終わった段階で呼ばれるイベント)、2つ目がLoad Event(すべての読み込みが完了した段階で呼ばれるイベント)です。
ブラウザはDOMツリーとスタイルルールからレンダーツリーを作り、レイアウトやペイントの処理へと進みます(厳密にはレンダリングエンジンによって若干異なります)。そのためレイアウトやペイントに進む前に発生するDOMContentLoaded Eventがどれだけ早く呼ばれるかということが、体感速度を測る指標の一つとなっています。
ここでは150px*150pxの画像を10個読み込む6つのサンプルを用意しています。
それぞれのサンプルで高速な通信回線とモバイル通信回線(Softbank LTE)を使い、DOMContentLoaded EventとLoad Eventが起こる時間を計測しました。
モバイル通信回線は回線状況に大きく影響されるため、傾向を出すに材料としては不十分です。参考程度の数値と思ってください。
※CDNにはAmazon CloudFrontを利用しています。
1. 6つのタイプとファイルサイズ
タイプ |
HTMLへのリンク による埋め込み |
CSSへのリンク による埋め込み |
インラインイメージ | |||
---|---|---|---|---|---|---|
Github(1) | CDN(2) | Github(3) | CDN(4) | HTML(5) | CSS(6) | |
HTMLの ファイルサイズ |
954B | 1,469B | 640B | 646B | 15,277B | 647B |
CSSの ファイルサイズ |
0B | 0B | 916B | 1,336B | 0B | 15,398B |
画像(10個)の ファイルサイズ |
14,000B | 14,000B | 14,000B | 14,000B | 0B | 0B |
タイプ(5)の場合、他のものと比べファイルサイズが約20倍にもなっています。
高速な通信回線の場合は問題なさそうですが、低速なモバイル通信回線の場合は逆に表示が遅く感じられてしまうかもしれません。
2. DOMContentLoaded Event
タイプ |
HTMLへのリンク による埋め込み |
CSSへのリンク による埋め込み |
インラインイメージ | |||
---|---|---|---|---|---|---|
Github(1) | CDN(2) | Github(3) | CDN(4) | HTML(5) | CSS(6) | |
平均値 | 132.9ms | 129.0ms | 128.1ms | 128.4ms | 128.1ms | 122.3ms |
1(キャッシュ無) | 145 | 123 | 119 | 119 | 124 | 118 |
2 | 124 | 133 | 127 | 119 | 119 | 113 |
3 | 125 | 136 | 120 | 138 | 123 | 134 |
4 | 142 | 122 | 118 | 121 | 128 | 142 |
5 | 130 | 129 | 130 | 126 | 124 | 118 |
6 | 146 | 128 | 131 | 129 | 128 | 116 |
7 | 127 | 128 | 123 | 129 | 136 | 129 |
8 | 118 | 130 | 132 | 137 | 121 | 115 |
9 | 138 | 131 | 139 | 122 | 138 | 118 |
10 | 134 | 130 | 142 | 144 | 140 | 120 |
高速な通信回線の場合、DOMContentLoaded Eventが起こる時間に大きな違いは見られません。
タイプ |
HTMLへのリンク による埋め込み |
CSSへのリンク による埋め込み |
インラインイメージ | |||
---|---|---|---|---|---|---|
Github(1) | CDN(2) | Github(3) | CDN(4) | HTML(5) | CSS(6) | |
平均値 | 858.2ms | 781.3ms | 743.3ms | 736.1ms | 769.2ms | 877.4ms |
1(キャッシュ無) | 926 | 514 | 497 | 513 | 253 | 433 |
2 | 939 | 951 | 663 | 641 | 1,480 | 631 |
3 | 655 | 647 | 734 | 695 | 483 | 654 |
4 | 1,000 | 914 | 882 | 895 | 729 | 908 |
5 | 916 | 747 | 601 | 692 | 1,160 | 698 |
6 | 725 | 933 | 899 | 869 | 1,180 | 1,300 |
7 | 905 | 754 | 704 | 585 | 1,070 | 1,340 |
8 | 907 | 948 | 899 | 872 | 1,710 | 613 |
9 | 674 | 727 | 882 | 695 | 895 | 1,500 |
10 | 935 | 678 | 672 | 904 | 442 | 697 |
モバイル通信回線の場合、インラインイメージの(5、6)はHTML/CSSのファイルサイズが大きいためか回線状況によって顕著に差がでるようです。