L'incorporation de données d'image d'arrière-plan dans CSS en tant que Base64 est-elle une bonne ou une mauvaise pratique?

475

Je cherchais la source d'un script utilisateur greasemonkey et j'ai remarqué ce qui suit dans leur CSS:

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

Je peux comprendre qu'un script greasemonkey voudrait regrouper tout ce qu'il peut dans la source plutôt que de l'héberger sur un serveur, c'est assez évident. Mais comme je n'avais pas vu cette technique auparavant, j'ai envisagé son utilisation et elle semble séduisante pour plusieurs raisons:

  1. Cela réduira le nombre de requêtes HTTP au chargement de la page, améliorant ainsi les performances
  2. S'il n'y a pas de CDN, cela réduira la quantité de trafic généré par les cookies envoyés avec les images
  3. Les fichiers CSS peuvent être mis en cache
  4. Les fichiers CSS peuvent être GZIPPED

Étant donné qu'IE6 (par exemple) a des problèmes de cache pour les images d'arrière-plan, cela ne semble pas être la pire idée ...

Alors, est-ce une bonne ou une mauvaise pratique, pourquoi NE L'UTILISEZ-VOUS PAS et quels outils utiliseriez-vous pour coder en base64 les images?

mise à jour - résultats des tests

Bien, mais ce sera un peu moins utile pour les petites images, je suppose.

MISE À JOUR: Bryan McQuade, un ingénieur logiciel chez Google, travaillant sur PageSpeed, a déclaré lors de ChromeDevSummit 2013 que data: uris en CSS est considéré comme un anti-modèle bloquant le rendu pour fournir un CSS critique / minimal lors de son discours #perfmatters: Instant mobile web apps. Voir http://developer.chrome.com/devsummit/sessions et gardez cela à l'esprit - diapositive réelle

Dimitar Christoff
la source
Faites des essais? Serait intéressant de voir à quel point la compression peut compenser le fait que vous encodez en base64.
Dykam
a publié les résultats du test, également disponibles sur mon blog fragged.org/…
Dimitar Christoff
5
Bonne question. Je voulais juste ajouter que cela ne fonctionne pas pour IE7 et les versions antérieures. Mais il y a quelques contournements. Voici un bel article à ce sujet jonraasch.com/blog/css-data-uris-in-all-browsers
MartinF
2
Ajout de plus de PRO:limites de cache sur les appareils cellulaires ... CON:certaines images doivent être traitées comme du contenu plutôt que comme une simple présentation et sont donc mieux adaptées aux balises HTML IMG qu'aux images d'arrière-plan CSS.
one.beat.consumer
1
@DimitarChristoff: J'ai été un fan de l'intégration de petites icônes avec base64 en raison de sa relative facilité (lors de la comparaison avec un sprite agressif) et j'étais heureux d'accepter la taille de la surcharge. Merci de remarquer que ce n'est pas toujours le cas (c. -à- gzip base64 Embed peut - être mieux en termes de taille d'actifs absolue ainsi)
ov

Réponses:

166

Ce n'est pas une bonne idée lorsque vous souhaitez que vos images et informations de style soient mises en cache séparément. De plus, si vous encodez une grande image ou un nombre important d'images dans votre fichier css, il faudra plus de temps au navigateur pour télécharger le fichier en quittant votre site sans aucune information de style jusqu'à la fin du téléchargement. Pour les petites images que vous n'avez pas l'intention de changer souvent, c'est une bonne solution.

en ce qui concerne la génération de l'encodage base64:

caca un birck
la source
less avait une fonction data-uri qui alignera
Luke Page
c'est une bonne idée si vous voulez avoir une protection minimale pour ces images afin qu'elles ne soient pas * mises en cache ou téléchargées par un clic droit -> enregistrer
vsync
"Ce n'est pas une bonne idée lorsque vous voulez que vos images et informations de style soient mises en cache séparément" - rien ne vous empêche d'avoir toutes les images dans un fichier .css séparé.
magritte
Ma pratique et mes tests ne confirment pas votre affirmation. Désolé.
TomeeNS
55

Cette réponse est obsolète et ne doit pas être utilisée.

1) La latence moyenne est beaucoup plus rapide sur mobile en 2017. https://opensignal.com/reports/2016/02/usa/state-of-the-mobile-network

2) multiplex HTTP2 https://http2.github.io/faq/#why-is-http2-multiplexed

Les «URI de données» doivent absolument être pris en compte pour les sites mobiles. L'accès HTTP sur les réseaux cellulaires s'accompagne d'une latence plus élevée par demande / réponse. Il existe donc des cas d'utilisation où le brouillage de vos images en tant que données dans des modèles CSS ou HTML pourrait être bénéfique sur les applications Web mobiles. Vous devez mesurer l'utilisation au cas par cas - je ne préconise pas que les URI de données soient utilisés partout dans une application Web mobile.

Notez que les navigateurs mobiles ont des limitations sur la taille totale des fichiers qui peuvent être mis en cache. Les limites pour iOS 3.2 étaient assez faibles (25K par fichier), mais deviennent plus grandes (100K) pour les nouvelles versions de Mobile Safari. Veillez donc à garder un œil sur la taille totale de votre fichier lorsque vous incluez des URI de données.

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

Mike Brittain
la source
23

Si vous référencez cette image une seule fois, je ne vois aucun problème pour l'intégrer dans votre fichier CSS. Mais une fois que vous utilisez plus d'une image ou devez la référencer plusieurs fois dans votre CSS, vous pouvez envisager d'utiliser une seule image image à la place, vous pouvez ensuite recadrer vos images uniques à partir de (voir Sprites CSS ).

Gombo
la source
16
Cela signifie simplement que vous devez avoir une classe css sur un élément pour référencer l'image d'arrière-plan et une autre classe css pour référencer les décalages dans cette image à utiliser pour cet élément.
Duncan Beevers, du
4
vous ne devriez PAS avoir de classes sur les éléments qui décrivent la façon dont le matériel est présenté - ces classes doivent être bien nommées et sémantiques (ce n'est pas toujours possible, mais bon pour tirer) Si plusieurs éléments utilisent la même image, et que vous souhaitez encodez cette image dans le CSS, laissez simplement l'image hors des déclarations, et utilisez une règle css ultérieure pour déclarer et incorporer l'image pour plusieurs sélecteurs / classes.
Adam Tolley
1
Si vous photographiez pour des cours sémantiques et que vous souhaitez également les données d'image une seule fois, vous pouvez avoir un style distinct qui répertorie tous les sélecteurs pertinents, puis des décalages définis dans des styles par sélecteur. Bien sûr, pour une très petite image dans beaucoup d'endroits, la liste de sélection pourrait être plus grande que les données ...
Leo
Afin d'éviter plusieurs classes et de ne spécifier une feuille de sprite qu'une seule fois, vous pouvez utiliser un sélecteur d'attribut:[emoji] {background-image: url(data:image/png;base64,qwedfcsfrtgyu/=);} [emoji=happy] {background-position: -20px 0px;}
Chinoto Vokro
21

L'une des choses que je suggérerais est d'avoir deux feuilles de style distinctes: une avec vos définitions de style régulières et une autre qui contient vos images en encodage base64.

Vous devez bien sûr inclure la feuille de style de base avant la feuille de style d'image.

De cette façon, vous vous assurerez que votre feuille de style régulière est téléchargée et appliquée dès que possible au document, tout en bénéficiant de demandes http réduites et d'autres avantages que les uris de données vous offrent.

ximi
la source
1
J'aime ça en théorie. Quelqu'un peut-il penser à des arguments contre?
Rob
J'étais juste en train de googler cela moi-même pour savoir si c'était une bonne idée et je suis venu ici. Dans mon cas, les images ne sont que des éléments d'interface utilisateur et je pensais que ce serait une bonne idée. Je ne sais pas si c'est mieux que d'utiliser des sprites CSS, mais je pense qu'il est plus facile à gérer si vous apportez des modifications à l'avenir. Aimeriez-vous savoir si quelqu'un a quelque chose contre cela?
Craig
20

Base64 ajoute environ 10% à la taille de l'image après GZipped, mais cela l'emporte sur les avantages en matière de mobile. Puisqu'il existe une tendance générale avec la conception de sites Web réactifs, il est fortement recommandé.

Le W3C recommande également cette approche pour les mobiles et si vous utilisez le pipeline d'actifs dans les rails, il s'agit d'une fonctionnalité par défaut lors de la compression de votre CSS

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

Greg
la source
bon point re mobile / responsive bien que je ne sois pas sûr des 10%, d'où obtenez-vous ces données?
Dimitar Christoff
3
C'est correct. La chose la plus lente dans tout appareil mobile est l'ouverture / fermeture des connexions http. Il est recommandé de les minimiser.
Rafael Sanches
malgré les résultats de w3, dans certains tests, j'ai fait augmenter la taille des images de ~ 25% :(
Fabrizio Calderan
2
Je suppose que cela peut augmenter jusqu'à 33% s'il est tout simplement impossible de le compresser.
Léon Pelletier
1
sur mobile 10% n'est rien comparé à la création de connexions http
Rafael Sanches
4

Je ne suis pas d'accord avec la recommandation de créer des fichiers CSS séparés pour les images non éditoriales.

En supposant que les images sont à des fins d'interface utilisateur, c'est le style de la couche de présentation, et comme mentionné ci-dessus, si vous faites de l'interface utilisateur mobile, c'est vraiment une bonne idée de conserver tous les styles dans un seul fichier afin de pouvoir les mettre en cache une fois.

Tim
la source
3

Dans mon cas, cela me permet d'appliquer une feuille de style CSS sans se soucier de copier les images associées, car elles sont déjà intégrées à l'intérieur.

Rolf
la source
3

J'ai essayé de créer un concept en ligne d'outil d'analyse CSS / HTML:

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

Ça peut:

  • Téléchargez et analysez les fichiers HTML / CSS, extrayez les éléments href / src / url
  • Détecter les données de compression (gzip) et de taille sur l'URL
  • Comparer la taille des données d'origine, la taille des données base64 et la taille des données base64 compressées
  • Convertissez l'URL (image, police, css, ...) en un schéma d'URI de données base64.
  • Compter le nombre de requêtes pouvant être épargnées par les URI de données

Les commentaires / suggestions sont les bienvenus.

Antonin

Antonin Foller
la source
3

Vous pouvez l'encoder en 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);
?>

La source

ucefkh
la source
2

Apportant un peu aux utilisateurs de Sublime Text 2, il existe un plugin qui donne au code base64 que nous chargeons les images dans le ST.

Appelé Image2base64: https://github.com/tm-minty/sublime-text-2-image2base64

PS: Ne sauvegardez jamais ce fichier généré par le plugin car il écraserait le fichier et le détruirait.

Daniel Santarriaga
la source
0

Merci pour les informations ici. Je trouve cette intégration utile et particulièrement pour les mobiles, en particulier avec le fichier css des images intégrées mis en cache.

Pour vous faciliter la vie, comme mes éditeurs de fichiers ne gèrent pas cela de manière native, j'ai créé quelques scripts simples pour le travail d'édition sur ordinateur portable / bureau, à partager ici au cas où ils seraient utiles à quelqu'un d'autre. Je suis resté avec php car il gère ces choses directement et très bien.

Sous Windows 8.1, dites ---

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

... là, en tant qu'administrateur, vous pouvez établir un raccourci vers un fichier de commandes dans votre chemin. Ce fichier batch appellera un script php (cli).

Vous pouvez ensuite cliquer avec le bouton droit sur une image dans l'explorateur de fichiers et envoyer au fichier de commandes.

Ok, demande Admiinstartor, et attendez que les fenêtres noires du shell de commande se ferment.

Ensuite, collez simplement le résultat du presse-papiers dans votre éditeur de texte ...

<img src="|">

ou

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

Les éléments suivants devraient être adaptables pour d'autres systèmes d'exploitation.

Fichier batch ...

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

Et avec php.exe sur votre chemin, cela appelle un script 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));

?>
PaulANormanNZ
la source
0

Pour autant que j'ai fait des recherches,

Utilisation: 1. Lorsque vous utilisez un sprite svg. 2. Lorsque vos images sont de taille inférieure (max 200 Mo).

N'utilisez pas: 1. Lorsque vous êtes de plus grandes images. 2. Icônes en svg. Comme ils sont déjà bons et compressés après compression.

Pooja Esakkimuthu
la source