Nous avons vu la compression côté serveur et la minification des fichiers JS et CSS.
Dans notre quête de performance, nous allons attaquer dans cet article les images.

Choix du format

Vous le savez sans doute, il existe plusieurs formats d’images pour le web : jpeg, png, gif pour ne citer que les principaux.

Le choix d’un format plutôt qu’un autre ne dépend pas uniquement de votre humeur. C’est en fonction de critères bien précis que vous allez choisir tel ou tel format.

Le format JPEG

C’est un format de destructeur. C’est à dire que l’image compressée est modifiée afin d’augmenter la compression. Plus la compression sera importante et plus la qualité de l’image sera mauvaise.

Le JPEG est bien adapté aux photos n’ayant pas d’aplat de couleur. La perte d’information se remarque beaucoup moins et, du coup, il est possible d’augmenter la compression.

Voilà un exemple d’image compressée en qualité 0 (mauvaise) et en qualité 60 (bonne) :

Compression Jpeg 0 - Photo

Compression Jpeg 0 - Photo

Compression Jpeg 60 - Photo

Compression Jpeg 60 - Photo

Je me remercie pour cette très jolie image ! Même avec une compression très forte, l’image reste « correcte ». En compression 0, l’image fait 7ko. En compression 60, elle fait 27ko. En compression minimale (100), l’image fait 86ko et ne présente pratiquement pas de différences visuelles avec la version compressée 60.

La même chose, mais cette fois-ci, avec un logo (logo du site WOO). Donc, avec des aplats de couleur :

Compression Jpeg 0 - Logo

Compression Jpeg 0 - Logo

Compression Jpeg 60 - Logo

Compression Jpeg 60 - Logo

La différence est plus nette ici. Le compression 0 fait 2.75ko. La 60 fait 7.64ko.

Le format PNG

Nous venons de voir que le format JPEG est bien adapté aux photos. Pour les images avec aplats de couleurs (logo, illustrations, …) le format PNG est plus adapté car c’est un format non destructeur. Il existe plusieurs formats d’encodage des PNG dont 2 nous intéressent ici : 8bits et 24bits.
Le 8bits dispose d’une palette de 256 couleurs maximum et éventuellement d’une couleur pour la transparence (1 seul niveau de transparence).
Le 24bits propose une palette plus importante (16 777 216 pour être précis) et éventuellement une couche alpha.

Passons tout de suite à un exemple :

Compression png 8bits - Photo

Compression png 8bits - Photo

Le nombre de couleurs a été réduit ici à 32. La photo ainsi compressée fait 23.3ko. Soit pratiquement autant que le Jpeg compressé à 60%. La qualité est pratiquement la même aussi. En 256 couleurs, l »image passe à 45ko. En 24bits, l’image passe alors à 134ko.

Pour obtenir une taille d’image identique à la compression Jpeg 0, il faut descendre le nombre de couleurs à 3. Ce qui nous donne cette image qui fait 7.6ko :

Compression png 3 couleurs - Photo

Compression png 3 couleurs - Photo

Comme indiqué plus haut, le format PNG est mieux adapté aux illustrations. Voici donc le logo repris avec ce format :

Compression png 8bits - Logo

Compression png 8bits - Logo

Cette image, compressée avec 64 couleurs, fait 3.4ko. Soit 50% de la version Jpeg de bonne qualité. La même image en 24bits fait 12.7ko.

Cas particuliers

Il existe tout de même des cas particuliers et notamment sur de petites images. Bien souvent, le format PNG vous permettra d’obtenir une image de poids inférieur au format Jpeg. Pour cela, réduisez le nombre de couleurs. Sur de petites images, bien souvent, vous ne ferez pas la différence.

Le format PNG n’aime pas les dégradés de couleurs. Donc, une illustration avec un beau dégradé sera certainement plus lourde que la même image en Jpeg à qualité égale. Voici un exemple :

Dégradé en Jpeg

Dégradé en Jpeg - 5ko

Dégradé en PNG 32 couleurs - 4ko

Dégradé en PNG 32 couleurs - 4ko

Dégradé en PNG 128 couleurs - 14ko

Dégradé en PNG 128 couleurs - 14ko

En 64 couleurs, l’image PNG fait approximativement 7ko, mais le dégradé n’est pas très joli.
Attention toutefois, cela n’est pas valable si le dégradé est horizontal ou vertical :

Compression dégradé horizontal 64 couleurs : 4.2Ko

Compression dégradé horizontal 64 couleurs : 4.2Ko

Le dégradé est correct et le poids est aussi bas que l’image Jpeg. En 128 couleurs, l’image atteint 8Ko.

Autre cas particulier qui se présente moins souvent et qui est donc méconnu : une image sur un fond de couleur identique. Par exemple, un logo avec un fond de couleur rouge sur une page ayant un fond de couleur rouge aussi. Vous devrez soit prendre le même format d’image pour le logo et pour le fond, soit définir le fond avec une couleur. En effet, si vous choisissez un Jpeg pour le logo et un PNG pour le fond, vous risquez d’avoir une différence de couleur entre le logo et le fond. Ce qui va faire ressortir le rectangle de l’image du logo.
L’exemple ci-dessous peut ne pas être flagrant en fonction de l’écran que vous avez. Il s’agit d’une copie d’écran sur Firefox. La couleur du logo (Jpeg) est #8B7EB6 et celle du fond (PNG) est #897CB5. Alors que les couleurs des images prisent séparément sont les mêmes.

Logo sur fond de couleur

Logo sur fond de couleur

Et le code HTML ?

Oui, il est aussi possible d’optimiser votre code HTML afin de rendre l’affichage des image plus rapide.

La première chose à faire est d’indiquer à chaque fois la largeur et la hauteur de l’image avec les attributs « width » et « height ». Pas avec un style, mais bien avec les attributs de la balise IMG. En effet, si vous indiquez les dimensions dans un fichier CSS (ou pire en inline), vous risquez d’avoir un reflow (rafraichissement de l’affichage par le navigateur).

Les sprites

Sprite www.faux-texte.com

Sprite www.faux-texte.com

Une technique d’optimisation consiste à regrouper les images en une seule afin d’accélérer le chargement. On a vu qu’à chaque chargement, le navigateur fait des aller/retour avec le serveur et que les navigateurs sont limité en connexions simultanées sur un même domaine.
L’image ci-contre vient du site Faux Texte qui utilise cette technique afin d’optimiser au maximum sont temps de chargement.

Google le fait déjà depuis longtemps. Amazon également.

Comment mettre cette technique en œuvre ? C’est en indiquant le fond dans un CSS que l’on va placer la bonne image au bon endroit :

.icon {
	display:block;
	overflow:hidden;
	line-height:60px;
	background-image: url(../images/sprites.png);
	background-repeat: no-repeat;
}
.iSprite1 {
	width:19px;
	height:11px;
	background-position: -33px -79px;
}

La class .icon va être utilisée pour l’ensemble des sprites. line-height est optionnel, mais permet de placer du texte dans le sprite (valeur à adapter) sans que ce texte se voit. À la place de line-height, vous pouvez également utiliser « text-indent:-9999px; » par exemple.
Vous pouvez également définir le display en « inline-block » afin de ne pas modifier le comportement de la balise utilisée.
La class suivante « iSprite1 » permet de donner les dimensions de l’image et sa position dans l’image globale.

Il suffit donc d’indiquer un lien de cette façon :

<a href="ma-page.htm" title="un lien" class="icon iSprite1">Un lien</a>

Pour fabriquer vos sprites, si vous n’avez ni Photoshop, ni Gimp, vous pouvez utiliser, par exemple, CSS Sprite Generator.

Pour compresser vos images correctement, vous avez Smushit comme outils en ligne.

La suite au prochain article !