Optimisation des images pour l’accélération d’un site web

En prenant comme exemple le travail réalisé pour voici.fr j’ai expliqué comment optimiser un site eZ Publish 4 pour l’utilisation des caches web, comment optimiser les performances de reverses proxy SQUID en amont de vos frontaux php, puis comment purger un élément de vos reverse proxy cache SQUID et au final démontré l’intérêt de ces optimisations avec le cas d’un pic d’audience du à l’action conjugué de Google Actu et Yahoo Actualité toujours sur Voici.fr

Maintenant je penche sur l’optimisation des images pour en accélérer le chargement afin de rendre plus véloce et rapide l’affichage des pages d’un site web.

 

Résolution et format mais la compression ?

Les images généré par les APN[1] sont d’une taille énorme et dépasse maintenant le millier de pixel de coté. Le contributeur à un site web à conscience de cela et s’efforce d’en réduire la résolution en général aidé en cela par une charte fournit par l’équipe technique en charge de la gestion du site web. Parfois un outils avec la procédure associée est fournit. Le plus les développeurs ont prévu des routines de vérification de la taille de l’image envoyé, parfois qui impose un format et ajoute une vérification du type mime.

Je me suis attaché à trouver une solution d’optimisation quelque soit la résolution en me concentrant sur le format jpg et png[2]. L’idée étant que le téléchargement d’une image de résolution raisonnable et d’un format précis ayant été acquit par le travail de vérification des routines mise en place par l’équipe de développement il me semblais nécessaire de revoir la compression et le nettoyage après la mise en ligne, ceci de façon automatique, massive et automatisable, bref à grand coup de script et cron.

 

Compression et nettoyage !

Les deux s’imposent de plus en plus avec l’utilisation massive d’APN et de logiciel de retouche d’image. Le premier comprime de moins en moins les images pour favorisé leur retouche ultérieurs. Un APN de type réflex propose d’ailleurs le format RAW ou TIFF qui ne comporte pas de compression. Mais en plus tout les types d’appareil, qui soit amateur ou professionnel ajoute tout un tas d’information dans le fichier en plus de l’image elle même:

  • Un court fichier d’en-tête pour organisation des bits, l’identification du fichier et l’emplacement des données.
  • Les métadonnées du capteur photographique ( la taille du capteur, filtre couleur et le profil couleur )
  • Les réglages d’exposition, le modèle d’appareil, la date voir la position GPS
  • section normalisée de métadonnées au format EXIF.
  • Parfois une vignette de l’image au format JPEG une prévisualisation rapide
  • etc.

Des informations très pertinente pour la retouche d’image ultérieur, le classement et l’archivage voir la gestion de droit mais totalement inutile pour l’utilisation sur le web. En plus de façon quasi systématique tout logiciel utilisé ultérieurement pour manipuler l’image ajoutera des informations semblable. Donc une nettoyage s’impose pour accélérer leur affichage.

 

Nettoyage et optimisation des JPG

Utilisation de jpegtran

Pour nettoyer les jpg j’ai utilisé jpegtran présent dans le paquet libjpeg-progs sous debian lenny. Mais d’autre solution existe vous pouvez en trouver une liste sur performance.survol.fr.

apt-get install libjpeg-progs

J’utilise les options suivante :

  • -copy none qui supprime tout le blabla enregistré par l’APN ou le logiciel de retouche
  • -optimize pour optimiser l’encodage en organisant les informations (sic)
  • -perfect impose que les deux précédentes option soient parfaitement réalisé ou pas du tout pour évité les situations partielles et instables.

Voici une ligne de commande pour traiter tout les jpg d’une arborescence. Noter que dans le bout de script suivant j’exclus les fichiers jpg ayant un espace dans leur nom ou dans le nom du répertoire de stockage.

for I in `find ./ -type f -name "*.jpg" | grep -v [[:space:]]`;  do jpegtran -copy none -optimize -perfect $I > /tmp/optimized.jpg; mv /tmp/optimized.jpg $I; done

Efficacité de jpegtran

Résultat un répertoire de 532 Fichiers qui pesait 53Mo est descendu à 50 Mo après optimisation avec jpegtran

 

Nettoyage et optimisation des PNG

Utilisation de pngcrush

Pour optimiser les png j’ai fais le choix de pngcrush présent sous debian lenny. La également d’autre solution existe entre autre optipng que linuxandfriends.com à testé.

J’utilise un option unique :

  • -brute teste 114 filtres de compression et ne retient que celui qui donne le meilleur résultat pour l’images traité.

Attention cela prend un temps énorme de réalisé 114 fois la compression d’une image pour au final n’en retenir qu’un résultat sur ce nombre. Mais, en contre partie, le filtre est toujours le plus pertinent pour l’image traité et résultat vraiment performant.

Voici une ligne de commande pour traiter tout les png d’une arborescence. Noter que dans le bout de script suivant j’exclus les fichiers png ayant un espace dans leur nom ou dans le nom du répertoire de stockage.

for I in `find ./ -type f -name "*.png" | grep -v [[:space:]]`;    do pngcrush -brute $I  /tmp/optimized.png; mv /tmp/optimized.png $I; done

Si vous souhaiter traiter uniquement les fichiers png du répertoire courant en changeant leur extension en .crush.png c’est plus simple :

pngcrush -brute -e ".crush.png" *.png

Les pgn de capture d’écran sous Mac OS X

Les capture d’écran sous Mas OS X avec la séquence de touche Pomme+shift+4 génère un fichier png par défaut. Personnellement j’utilise beaucoup cette fonction pour créé les images illustrant mes articles. La méthode / filtre la plus efficace de pngcrush pour ces png est la 113. Voici la syntaxe de son utilisation :

pngcrush -m 113 -e ".crush.png" *.png

Efficacité de pngcrush

Sur un répertoire contenant à l’origine les trois images png suivante.

-rwxr-xr-x 1 www-data www-data 365K Oct 13 16:00 Header.home.Voici.fr.png -rwxr-xr-x 1 www-data www-data 268K Oct 13 16:00 Hearder.Logo.Voici.fr.png -rwxr-xr-x 1 www-data www-data 284K Oct 13 16:03 Taille.Element.Voici.fr.png

Nous arrivons au résultat suivant

-rw-r--r-- 1 root     root     238K Oct 13 16:00 Header.home.Voici.fr.crush.png -rw-r--r-- 1 root     root     173K Oct 13 16:00 Hearder.Logo.Voici.fr.crush.png -rw-r--r-- 1 root     root     189K Oct 13 16:03 Taille.Element.Voici.fr.crush.png

Avant nous avions 900K d’image png, maintenant nous avons 600K. Sur cet exemple, limité, le poids des images à été réduit d’un tiers.

Notes

[1] appareil photo numérique

[2] Gif is dead

11 réflexions sur “ Optimisation des images pour l’accélération d’un site web ”

  1. Merci pour les infos.

    Si tu utilises image magick pour convertir des images lors du traitement ne pas oublier l’option profile qui réduit de manière drastique la taille de l’image en supprimer toutes les infos complémentaires de la photo.

    convert +profile '*' source dest

    Doc profile sur imagemagick

  2. Merci pour tes posts très utile.

    La commande pngcrush que tu donnes ne supprime pas certaines données texte inutiles tels que « software » (« Adobe ImageReady » par exemple)
    Donc on peut gagner encore quelques octets avec :
    pngcrush -rem text -brute image.png out.png

  3. Pour eZ publish, on peut ajouter automatiquement la commande profile.

    Dans votre fichier image.ini.append.php, vous pouvez rajouter dans la section ImageMagick

    PreParameters=+profile ‘*’

    Cela va permettre à chaque image uploadée dans eZ publish d’être nettoyée

  4. Depuis quelques semaines, j’ai remplacé pngcrunch par advpng. ça me permet de gratter quelques octets.

    Install sous Debian : « apt-get install advancecomp »
    Utilisation : « advpng -z2 image.png »
    On peut remplacer z2 par z3 ou z4 pour encore plus compresser…

    Je précompresse aussi les jpeg au format gzip avec 7zip et cette commande : « 7z a -tgzip -mx9 image.jpg.gz image.jpg ». ça permet de gratter encore quelques octets et j’évite au serveur de recompresser les mêmes images à chaque requête.

  5. Merci Olivier d’avoir partagé tes astuces. Je note pour la pré-compression que je testerais certainement bientôt.

  6. De rien Karles, merci pour ton blog qui est bien pratique 🙂

    J’oubliais de préciser : mon serveur web est nginx et pour les fichiers précompressés j’utilise la directive « gzip_static on; » : http://wiki.nginx.org/HttpGzipStati
    Je suppose qu’il existe la même chose pour apache et les autres.

  7. Merci Nicolas mais jpegmini c’est un outil commercial. jpegtan est un logiciel libre et en trois ligne de bash vous automatisez le traitement facilement. C’est une solution rustique … je préfère le rustique 😀

Laisser un commentaire