背景画像のデータをBase64としてCSSに埋め込むことは良い習慣ですか、それとも悪い習慣ですか?


475

私はgreasemonkeyのユーザースクリプトのソースを見ていたところ、CSSに次のことがわかりました。

.even { background: #fff url(data:image/gif;base64,R0lGODlhBgASALMAAOfn5+rq6uvr6+zs7O7u7vHx8fPz8/b29vj4+P39/f///wAAAAAAAAAAAAAAAAAAACwAAAAABgASAAAIMAAVCBxIsKDBgwgTDkzAsKGAhxARSJx4oKJFAxgzFtjIkYDHjwNCigxAsiSAkygDAgA7) repeat-x bottom}

greasemonkeyスクリプトは、サーバー上でホストするのではなく、ソース内で可能なすべてのものをバンドルすることを望んでいることを理解できます。しかし、このテクニックを以前に見たことがなかったので、その使用を検討しましたが、いくつかの理由で魅力的であると思われます。

  1. ページ読み込み時のHTTPリクエストの量を減らし、パフォーマンスを向上させます
  2. CDNがない場合は、画像とともに送信されるCookieによって生成されるトラフィックの量が減少します
  3. CSSファイルをキャッシュできます
  4. CSSファイルはGZIPPEDできます

IE6(例えば)が背景画像のキャッシュに問題があることを考えると、これは最悪の考えではないようです...

それで、これは良い習慣か悪い習慣ですか、なぜそれを使用せず、画像をbase64エンコードするためにどのツールを使用するのですか?

更新-テストの結果

いいですが、小さい画像にはあまり役に立たないと思います。

更新:Googleのソフトウェアエンジニア、ブライアンマクエードは、PageSpeedに取り組んでおり、ChromeDevSummit 2013で、CSSのdata:urisは、講演中にクリティカル/最小限のCSSを提供するためのレンダリングブロッキングアンチパターンと見なされると述べました#perfmatters: Instant mobile web appshttp://developer.chrome.com/devsum​​mit/sessionsを参照してください。実際のスライド


テストを実行しますか?base64でエンコードするという事実をどれだけ圧縮できるかは興味深いでしょう。
Dykam 2009

テストの結果を掲示し、また私のブログ上で役に立つfragged.org/...
ディミタール・クリストフ

5
良い質問。IE7以下では機能しないことを追加したかっただけです。しかし、いくつかの回避策があります。ここではそれについての素晴らしい記事がされjonraasch.com/blog/css-data-uris-in-all-browsers
MartinF

2
PRO:携帯デバイスのキャッシュ制限を追加します... CON:一部の画像は単純なプレゼンテーションではなくコンテンツとして扱われる必要があるため、CSSの背景画像よりもHTML IMGタグに適しています。
one.beat.consumer

1
@DimitarChristoff:私は(アグレッシブなスプリッティングと比較すると)比較的簡単であるため、base64で小さなアイコンを埋め込むのが好きで、サイズのオーバーヘッドを受け入れてよかったです。常にそうであるとは限らないことを指摘していただきありがとうございます(つまり、gzipされたbase64埋め込みは、絶対的なアセットサイズの点でも優れている可能性があります)
ov

回答:


166

画像とスタイル情報を別々にキャッシュしたい場合はお勧めできません。また、大きな画像または大量の画像をcssファイルにエンコードする場合、ブラウザーがファイルをダウンロードするのに時間がかかり、ダウンロードが完了するまで、スタイル情報なしでサイトを離れます。小さな画像の場合は、頻繁に変更するつもりはないが、それでも良い解決策です。

base64エンコーディングを生成する限り:


lessには画像をインライン化するdata-uri関数がありましたlesscss.org/#reference
Luke Page

これらの画像を最小限の保護で保護したい場合は、画像がキャッシュされないようにするか、右クリックしてダウンロードできるようにすることをお勧めします->保存
vsync

「画像とスタイル情報を別々にキャッシュしたい場合、それは良い考えではありません」-すべての画像を別々の.cssファイルに保存することを妨げるものは何もありません。
magritte 2014

私の練習とテストはあなたの発言を確認しません。ごめんなさい。
TomeeNS

55

この回答は古くなっているため、使用しないでください。

1)2017年のモバイルの平均レイテンシははるかに高速です。https://opensignal.com/reports/2016/02/usa/state-of-the-mobile-network

2)HTTP2マルチプレックス https://http2.github.io/faq/#why-is-http2-multiplexed

「データURI」は、モバイルサイトでは必ず検討する必要があります。セルラーネットワーク経由のHTTPアクセスでは、リクエスト/レスポンスあたりのレイテンシが高くなります。そのため、CSSまたはHTMLテンプレートへのデータとしての画像のジャムがモバイルWebアプリで有益な場合があるいくつかの使用例があります。使用状況はケースバイケースで測定する必要があります-データURIをモバイルWebアプリのあらゆる場所で使用する必要があるとは主張していません。

モバイルブラウザでは、キャッシュできるファイルの合計サイズに制限があることに注意してください。iOS 3.2の制限はかなり低い(ファイルあたり25K)が、新しいバージョンのMobile Safariでは大きく(100K)なっている。したがって、データURIを含める場合は、ファイルの合計サイズに注意してください。

http://www.yuiblog.com/blog/2010/06/28/mobile-browser-cache-limits/


23

その画像を1度だけ参照しても、CSSファイルに埋め込む問題は発生しません。ただし、複数の画像を使用するか、CSSで複数回参照する必要がある場合は、代わりに単一の画像マップを使用して、単一の画像を切り取ることができます(CSSスプライトを参照)。


16
これは、背景画像を参照するための要素に1つのcssクラスがあり、その要素に使用する画像へのオフセットを参照するために別のcssクラスが必要であることを意味します。
Duncan Beevers

4
マテリアルの表示方法を説明する要素にクラスを含めないでください。これらのクラスは、適切な名前で意味論的である必要があります(これは常に可能とは限りませんが、撮影に適しています)複数の要素が同じ画像を使用していて、 CSSでその画像をエンコードし、宣言から画像を除外し、後のcssルールを使用して、複数のセレクター/クラスの画像を宣言して埋め込みます。
Adam Tolley、2012年

1
セマンティッククラスを撮影していて、画像データも1回だけ必要な場合は、関連するすべてのセレクターをリストする個別のスタイルを用意し、セレクターごとのスタイルでオフセットを定義できます。もちろん、多くの場所にある非常に小さな画像の場合、セレクターリストがデータよりも大きくなる可能性があります...
Leo

複数のクラスを避けるために、一度だけスプライトシートを指定するには、属性セレクタを使用することができます[emoji] {background-image: url(data:image/png;base64,qwedfcsfrtgyu/=);} [emoji=happy] {background-position: -20px 0px;}
Chinoto Vokro

21

私が提案することの1つは、2つの個別のスタイルシートを用意することです。1つは通常のスタイル定義を使用し、もう1つはbase64エンコーディングで画像を含むものです。

もちろん、画像スタイルシートの前にベーススタイルシートを含める必要があります。

このようにして、通常のスタイルシートがダウンロードされ、ドキュメントにできるだけ早く適用されることを保証すると同時に、httpリクエストの削減や、データURIがもたらすその他のメリットから利益を得ます。


1
私は理論的にこれが好きです。誰もが反対意見を考えることができますか?
Rob

これを自分でググリングして、それが良いアイデアかどうかを調べて、ここに来ました。私の場合、画像はすべてUIのものであり、これは良いアイデアだと思っていました。cssスプライトを使用するよりも優れているかどうかはわかりませんが、将来変更した方が管理しやすいと思います。誰かこれに対して何かがあるかどうか知りたいですか?
Craig

20

Base64はGZipped後の画像サイズに約10%を追加しますが、モバイルに関してはそれを上回る利点があります。レスポンシブWebデザインには全体的な傾向があるため、強くお勧めします。

W3Cはモバイルにもこのアプローチを推奨しており、レールでアセットパイプラインを使用する場合、これはCSSを圧縮するときのデフォルトの機能です

http://www.w3.org/TR/mwabp/#bp-conserve-css-images


10%かどうかはわかりませんが、モバイル/レスポンシブの良い点はどこからデータを取得しているのですか?
Dimitar Christoff 2012年

3
これは正しいです。モバイルデバイスで最も遅いのは、http接続のオープン/クローズです。それらを最小化することをお勧めします。
ラファエルサンチェス

w3の結果にもかかわらず、いくつかのテストでは、画像のサイズを最大25%増加しました:(
Fabrizio Calderan '28

2
それを圧縮することが単に不可能であるならば、それは33%まで上がることができると思います。
レオン・ペルティエ

1
モバイルでの10%は、http接続の作成に比べて何もありません
Rafael Sanches

4

非エディトリアル画像用に個別のCSSファイルを作成するという推奨に同意しません。

画像がUIの目的であると仮定すると、それはプレゼンテーションレイヤーのスタイリングです。前述のように、モバイルUIを実行している場合は、すべてのスタイリングを1つのファイルに保持して一度にキャッシュできるようにすることをお勧めします。


3

私の場合、関連する画像は既に内部に埋め込まれているため、コピーすることを心配することなく、CSSスタイルシートを適用できます。


3

CSS / HTMLアナライザーツールのオンラインコンセプトを作成してみました。

http://www.motobit.com/util/base64/css-images-to-base64.asp

できる:

  • HTML / CSSファイルをダウンロードして解析し、href / src / url要素を抽出します
  • URLの圧縮(gzip)とサイズデータを検出する
  • 元のデータサイズ、base64データサイズ、gzip圧縮されたbase64データサイズを比較する
  • URL(画像、フォント、cssなど)をbase64データURIスキームに変換します。
  • データURIによって回避できる要求の数を数える

コメント/提案は大歓迎です。

アントニン


3

あなたはそれをPHPでエンコードすることができます:)

<img src="data:image/gif;base64,<?php echo base64_encode(file_get_contents("feed-icon.gif")); ?>">

Or display in our dynamic CSS.php file:

background: url("data:image/gif;base64,<?php echo base64_encode(file_get_contents("feed-icon.gif")); ?>");

1 That’s sort of a “quick-n-dirty” technique but it works. Here is another encoding method using fopen() instead of file_get_contents():

<?php // convert image to dataURL
$img_source = "feed-icon.gif"; // image path/name
$img_binary = fread(fopen($img_source, "r"), filesize($img_source));
$img_string = base64_encode($img_binary);
?>

ソース



0

ここに情報をありがとう。私はこの埋め込みが便利で、特にモバイルで特に埋め込み画像のcssファイルがキャッシュされている場合に便利です。

私のファイルエディタはこれをネイティブで処理しないため、作業を簡単にするために、ラップトップ/デスクトップの編集作業用の簡単なスクリプトをいくつか作成しました。私はphpをそのまま使用しているのは、これらの処理を直接かつ非常にうまく行っているからです。

Windows 8.1の下で言う---

C:\Users\`your user name`\AppData\Roaming\Microsoft\Windows\SendTo

...管理者として、パスにバッチファイルへのショートカットを設定できます。そのバッチファイルは、php(cli)スクリプトを呼び出します。

次に、ファイルエクスプローラーで画像を右クリックし、バッチファイルを送信します。

Admiinstartorリクエストに同意し、黒いコマンドシェルウィンドウが閉じるまで待ちます。

次に、クリップボードの結果をテキストエディターに貼り付けるだけです...

<img src="|">

または

 `background-image : url("|")` 

以下は他のOSにも対応できるはずです。

バッチファイル...

rem @echo 0ff
rem Puts 64 encoded version of a file on clipboard
php c:\utils\php\make64Encode.php %1

パスにphp.exeを使用すると、php(cli)スクリプトが呼び出されます...

<?php 

function putClipboard($text){
 // Windows 8.1 workaround ...

  file_put_contents("output.txt", $text);

  exec("  clip < output.txt");

}


// somewhat based on http://perishablepress.com/php-encode-decode-data-urls/
// convert image to dataURL

$img_source = $argv[1]; // image path/name
$img_binary = fread(fopen($img_source, "r"), filesize($img_source));
$img_string = base64_encode($img_binary);

$finfo = finfo_open(FILEINFO_MIME_TYPE); 
$dataType = finfo_file($finfo, $img_source); 


$build = "data:" . $dataType . ";base64," . $img_string; 

putClipboard(trim($build));

?>

0

私が調査した限りでは

使用:1. svgスプライトを使用している場合。2.画像​​のサイズが小さい場合(最大200MB)。

使用しないでください:1.大きい画像の場合。2. svgとしてのアイコン。それらはすでに良好であり、圧縮後にgzipされているため。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.