Des images encodées en Base64 pour accélérer le chargement de sa page en diminuant les requètes

[ 11 ] Commentaires
Share

J’en ai déjà parlé plusieurs fois : accélérer le temps de chargement d’un site passe entre autre par la réduction du nombre de fichiers à charger, car chaque requète supplémentaire nécessite un temps non compressible pour appeler le serveur, établir une connexion, et télécharger le fichier. Cela peut passer par la transformation des images en pixels CSS, ou bien également pas leur définition en Base64. Je n’avais jusqu’alors pas trop regardé cette solution en terme d’avantages apportés, mais j’aurais dû, comme je l’explique ci-dessous.   

Le rapport entre le billet et l’image ? Y’en a pas (à part l’idée de vitesse et de lumière). Cela dit, j’aimais bien ce fond d’écran, il est téléchargeable là.

Je me suis donc repenché sur le sujet après être tombé sur un billet traitant du sujet, et voilà quelques améliorations que j’ai vues possibles sur ce blog. J’ai découpé mes tests en trois, étalant la taille des fichiers (d’une centaine d’octets à plusieurs dizaines de Ko), afin de voir à partir de quelle limite de taille l’utilisation de Base64 n’est plus justifiée.

Premier test

Mon image de fond, disponible a cette adresse, me coûte 138 octets en PNG.

En la passant en Base64 (avec ce site), j’obtiens la chaine de caractère suivante :

data:image/png;base64,
iVBORw0KGgoAAAANSUhEUgAAA+gAAAABAgMAAAAwbmygAAAAB
GdBTUEAALGPC/xhBQAAAAlwSFlzAAASdAAAEnQB3mYfeAAAAAxQ
TFRFAAAA1tjD3N3K////dy6oVgAAABRJREFUCB1j+D8ogWgouSBoFbE
AAAa9w/mxw3JEAAAAAElFTkSuQmCC

Or, cette chaîne de caractère, une fois mise dans la feuille CSS, ne prend que 207 octets, soit donc un peu mois de deux fois plus. L’avantage du CSS, c’est qu’on peut le gzipper. Et une fois gzippée, cette chaîne de caractère prend… 201 octets, ce qui n’est pas fantastique, bien sûr, mais je suis prêt à parier que le temps de téléchargement supplémentaire des 201-138=63 octets est négligeable par rapport à celui de l’établissement d’une nouvelle connexion. En effet, sur des fichiers envoyés par Nginx, je remarque souvent un temps d’attente+connexion de 30 ms ( ce qui est déjà pas mal, et je pense que vous aurez du mal à trouver un temps inférieur sur le net). Or, à un taux de téléchargement de 50ko/s (taux finalement assez faible par rapport aux connexions moyennes que j’ai), le téléchargement de 63 octets représente : 1,2ms de téléchargement supplémentaire (règle de 3 : (63*1000)/(50*1024) = 1,2). Une broutille, comparé aux 30ms de temps de connexion occasionné par un requète supplémentaire !

En conclusion : pour ce fichier, le Base64 multiplie par un facteur de 30 (au minimum) le chargement de cette ressource.

Deuxième test

Avec une image un peu plus importante, celle d’un icone pointant vers le compte Twitter d’AbriCoCotier.

  • En JPG, elle fait 9216 octets.
  • En Base64 non-gzippée : 12311 octets.
  • En Base64 gzippée : 9340 octets (soit donc 9340-9216=124 octets de plus). Or, à un taux de téléchargement de 50ko/s, le téléchargement de 124 octets représente : 2,4ms de téléchargement supplémentaire (règle de 3 : (124*1000)/(50*1024) = 2,4).

Donc là aussi, le pourcentage d’octets en plus après encodage Base64+ gzip reste bien inférieur (là avec un facteur de 15) à ce qu’aurait occasionné le téléchargement d’une autre ressource.

Troisième test

Avec le header de la page, qui est sans aucun doute l’image la plus lourde de la page.

  • En JPG, elle fait 34241 octets (je ne donne que les comptes en octets, dans la mesure où Linux me fournit des Kio et non des Ko, donc je préfère éviter toute confusion).
  • En base64 non gzippée, 45682 octets.
  • En Base64 gzippée, 34242 octets.

Pour ce fichier, en Base64 gzippée, on arrive à une taille inférieure à celle du JPG (ou quasi égale, à un octet près), tout en économisant en plus le temps de connexion supplémentaire ! Donc c’est directement le temps de téléchargement final de la page qui est amélioré. Surtout, je crois que le plus important est de noter que la taille de l’image étant assez importante, le gzip semble (progressivement) plus efficace pour encoder le contenu de l’image que l’encodage JPG lui-même ! C’est donc de très bonne augure pour les reste des grosses images à charger.

Bilan

J’ai l’impression que quelque soit la taille des fichiers, on est gagnant avec Base64 :

  • soit les fichiers sont petits, auquel cas la taille Base64+gzip est légèrement supérieure à celle d’origine, mais cette taille supérieure permet d’économiser quand même beaucoup plus de temps de téléchargement qu’on en aurait perdu en allant chercher une ressource supplémentaire ;
  • soit les fichiers sont très gros, auquel cas la taille Base64+gzip parvient à être encore plus faible que la taille d’origine !

Malgré tout, je ne recommande pas forcément l’utilisation de cette technique. Son gros point faible reste de ne pas être interprétée par IE6 et IE7, qui peuvent, selon les sites, représenter une part importante du trafic. Pour AbriCoCotier.fr, le trafic venant des Internet Explorer toute version confondue est de 30,90%, dont 67,98% d’IE8 (qui interprète correctement le Base64). Je considère que les autres versions ne supportent pas le Base64. Sur le total des visiteurs, j’en ai donc 0,3090*(1-0,6798)=0,0989 soit donc en gros 10% qui ne pourront pas voir ces images. Je considère que c’est trop élevé, mais je suis sûr que d’autres sites ont des statistiques à ce niveau qui sont bien plus flatteuses, et donc qui leur permettent de faire ce pas en avant.

Edit : J’ai fait un outil en ligne pour encoder vos images en Base64, ce qui vous permettra de comparer directement si l’original est plus lourd que le Base64 gzippé.

Vous serez peut-être intéressé :

11 commentaires sur ce billet

  1. rangzen dit :

    C’est gagnant sur 1 seule connexion mais en perdant toute la gestion du cache ça doit très vite s’inverser …

    RépondreRépondre
  2. Louis dit :

    @rangzen: Non, parce que le CSS est lui aussi mis en cache ! Donc tu ne le perds pas à ce niveau. Je pense que tu perds en terme de référencement sur les images (donc faut le faire sur des images sur lesquelles tu n’as aucun trafic entrant).

    RépondreRépondre
  3. rangzen dit :

    @Louis: Ah ok dans le CSS … C’est jolie comme technique mais … quelle horreur 🙂

    RépondreRépondre
  4. Louis dit :

    @rangzen: Ah oui ça je suis bien d’accord, c’est purement immonde.

    RépondreRépondre
  5. Eroan dit :

    Mais tellement efficace ! Je l’avais anticipé le coup du « ça ne sera pas mis en cache » dans mon article 😉

    Merci pour la citation d’ailleurs, ça m’a ramené un peu de monde, et ça permet de communiquer sur cette technique encore assez peu connue…

    RépondreRépondre
  6. max dit :

    Tres interessant, par compte j’ai du mal à saisir comment 34242 est inférieur à 34241. (3eme test)

    RépondreRépondre
  7. Interessant. J’avais vu cette technique mais je ne m’y étais pas trop penché.

    Perso j’ai fait un choix radical : HTML5 et CSS3 à fond pour mon prochain design, autant dire que IE6, 7 et même 8…..

    RépondreRépondre
  8. Louis dit :

    @Eroan: PAs de problème, ton billet le méritait.

    @max: Oui, j’ai modifié. Mais il y a vraiment certaines images qui sont plus légères en Base64 gzippé plutôt qu’en version originale. Par exemple : http://abricocotierfr.appspot.com/base64encoder?q=http://www.abricocotier.fr/wp-content/uploads/2010/07/Light_Contact_by_Faellas.jpg

    @Lionel – Websourcing.fr: Oui, moi aussi je pense que ça va se finir comme ça. J’en ai marre des navigateurs hors d’âge. Ils représentent une part constamment décroissante du trafic (même si leur taux de clic est bien plus élevé), donc je vais finir par ne plus m’en préoccuper du tout… Déjà que je ne teste jamais mes applis sur IE5/6/7/8 😀

    RépondreRépondre
  9. Bon je viens de passer pas mal de petits fichiers image en base64, merci pour ton outil !

    RépondreRépondre

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *