Encodage d’images en Base64 et vitesse de chargement

écrit par Aymeric

Suite à l'article de Daniel Roch sur les différentes manières pour optimiser les performances d’un thème WordPress , je voulais rajouter mon petit grain de sel sur une optimisation parfois très efficace concernant les images. Cette astuce consiste à encoder les images en Base64.
Mais c'est quoi ce "Base 64" Aymeric? Pour ceux qui ne connaissent pas et si l'on s'en tient à la définition de Wikipédia, "base64 est un codage de l'information utilisant 64 caractères, choisis pour être disponibles sur la majorité des systèmes." Nous allons utiliser ce codage pour représenter des données binaires dans du texte. Je vous ai perdu? déja? Bon, fin de l'intro...

Un fichier image absent du serveur

Pour vous expliquer les choses à ma manière et sans vous parler de 2×6 = 8+4 = 12 bits comme wikipédia, on envoie une chaîne de caractères en base64 à l'internaute via un schéma d'URI (Data URI, URI=Uniform Resource Identifier) dans la page HTML, cette chaîne est ensuite décodée par le navigateur pour afficher l'image. Plutôt que des paroles, cherchez plutôt l'URL de cette image:

Vous avez vu? il n'y en a pas. Et c'est là tout l'intérêt. Mais à qui cela profite? à l'internaute ou au serveur? "Les deux mon capitaine!"

Moins de requêtes mais plus d'octets

L'un des gros avantages de cette technique d'affichage pour les images réside dans le fait qu'elle limite le nombre de fichiers à télécharger par le navigateur et donc le nombre de requêtes ce qui se traduit par des temps de réponses sur le serveur Web en moins.

En cas de forte d'affluence sur votre blog (suite à la rédaction d'une revue du web par exemple), vous soulagerez votre serveur de quelques connexions de trop.
C'est aussi un plus du côté de l'internaute. Il faut savoir que les navigateurs ont une limite de quelques connexions simultanées par domaine. Moins il y aura de ressources à charger simultanément, plus les éléments se chargeront rapidement pour afficher la page. À priori tout cela est positif, mais il y a malgré tout quelques inconvénients...

1er problème, Internet Explorer: certains navigateurs comme IE5,IE6 et IE7 ne supportent pas l'encodage en Base64, ce qui représente encore une petite partie du gâteau.

2ème problème, le poids des pages: ces données images contenues sous la forme de texte au sein de votre code source vont gonfler la taille de votre page HTML. Pour l'image ci-dessus par exemple, on rajoute 8635 octets à la page (l'image JPG originale ne pèse que 6459 octets). Avec la compression Gzip activée sur le serveur, cela réduit quelque peu la taille de la page finale.
Mais si on utilise l'encodage des images en base64 pour une image récurrente entre plusieurs pages d'un site, on alourdit le poids de toutes les pages et cela ne devient plus tellement avantageux.

3ème problème, image non physique: comme l'image n'est pas physiquement sur votre serveur, vous allez devoir passer par un encodeur comme celui-ci : http://www.greywyvern.com/code/php/binary2base64. A chaque modification de votre image, vous devrez passer par un outil qui effectuera l'encodage. Pas très souple comme solution...

Utiliser l'encodage en Base64 à mon escient

D'après un test ultra complet sur les images en base64 vs fichiers binaires, il faudrait choisir pour une feuille de style accompagnée de 5 images entre 130.986 octets et 5 requêtes HTTP ou 133.615 octets en 1 requête HTTP.
Pour gagner en performance, on va réduire les temps de réponse, et avec des feuilles de styles qui seront mises en cache par la suite, on ne va pas télécharger chaque image en base 64 à chaque chargement de page. Pour implémenter les images sur votre site, voici les méthodes avec le Data URI scheme data:[<MIME-type>][;charset=<encoding>][;base64],<data>:

Pour le HTML:

<img src="data:image/png;base64,GerehZhmeZG8xdpHQ4rO66GnK+pWmycgDn3q00Di+g2G0uJmAXPPtUyqRQRpSZfh0eeKZROpXPINZusjVUGXriIxnyzhVXgLjrWaldlOFkZ9zdpEAqjkD6V0RMGYsknmSsx......">

Pour les CSS:

monheader{
 background:url(data:image/png;base64,GerehZhmeZG8xdpHQ4rO66GnK+pWmycgDn3q00Di+g2G0uJmAXPPtUyqRQRpSZfh0eeKZROpXPINZusjVUGXriIxnyzhVXgLjrWaldlOFkZ9zdpEAqjkD6V0RMGYsknmSsx......);
}

Heureusement pour vous éviter de faire la gymnastique je modifie mon image, je l'encode en base64, PHP a créé pour vous une fonction bien pratique pour encoder en base 64 à la volée et qui s'intitule base64_encode().
Notre ligne précédente (sous réserve que l'on génère dynamiquement notre feuille de style via une règle Apache RewriteRule (.*).css /$1.php) donnera donc:

monheader{
 background:url(data:image/gif;base64,<? base64_encode(file_get_contents('monimage.jpg'))?>;);
}

Et là, ça devient intéressant. Pour une feuille de style qui contient une vingtaine d'images, on va économiser pas mal de requêtes! ... C'est donc essentiellement dans les CSS que l'encodage en Base64 est pertinent, pour tout ce qui va concerner les décorations/habillage d'un site. N'oubliez pas que les sprites CSS existent aussi, mais bon le codage en base64, c'est vraiment un truc de geek:)

et Google Images?

Etant donné que les images n'existent que virtuellement via du texte, Googlebot-Image/1.0 ne va pas indexer ce type d'images. Cela n'a pas réellement d'impact si vous utiliser ce système pour vos feuilles de style. Par contre, cela peut s'avérer intéressant mais totalement illégal si vous volez du contenu image et que vous ne voulez pas vous faire repérer... A l'inverse, utiliser le codage en Base 64 pour des images que vous ne souhaitez pas retrouver dans l'index de Google Images est une bonne solution (et oui, Googlebot et le robots.txt ne font pas toujours bon ménage...)

Conclusion: L'encodage en base64 est utile pour les CSS. Et vous, avez vous déjà intégré vos images de cette manière?

écrit dans Astuces par Aymeric | 21 commentaires

21 commentaires "Encodage d’images en Base64 et vitesse de chargement"

  • Benoit dit:
  • lionel dit:
  • Daniel Roch dit:
  • John Doe dit:
  • cdillat dit:
  • tonguide dit:
  • Le Juge dit:
  • Thomas dit:
  • Edouard dit:
  • Aurélien dit:
  • rudrud dit:
  • Maxime dit:
  • tsoudaz dit:
  • Philippe dit:
  • Soul dit:
  • paiement internet dit:
  • Sarouel dit:
  • EliseRefd dit:
  • julien dit:
    • Aymeric dit:
    • Aymeric dit: