title: Images et performances
slug: images-performances
date: 2015-11-02
chapo: Exemple d’expérimentation technique.

> On this site, we use a lot of images within our content. As the person who maintains this site, I do my best to optimize them, but in many cases the sum total of the image weight on a page is still significant (especially as we’ve come to rely on animated GIFs for illustrations). The thing is, much of this image weight sits well offscreen. As much as I’d like to believe that every visitor reads every word we write, it’s highly likely that many visitors are downloading images that they simply do not ever see.
>
> <cite>*[Lazy Loading Images on the Web](http://developer.telerik.com/featured/lazy-loading-images-on-the-web/)* ([cache](/david/cache/911d8d2cce04195fe21b4efeaa0e25cb/))</cite>

Suite des [expérimentations techniques](/david/blog/2015/experimentations-techniques/), je demande aux [étudiants](/david/pro/enseignement/) de rédiger un article en groupe sur ce qu’ils ont testé pendant la matinée sur une thématique donnée (cet article sert d’exemple). Cette semaine : les images. L’après-midi leur permet de présenter à l’oral le fruit de leurs découvertes à l’ensemble de la promotion et pour moi de faire des rappels, des remarques et de m’assurer que la base a été comprise.

J’ai choisi d’explorer le chargement des images asynchrones ce qui permet de revoir la définition d’une image en HTML5 :

    :::html
    <figure>
        <img src="image.jpg" alt="Texte décrivant l'image">
        <figcaption>
            Légende pas forcément descriptive
        </figcaption>
    </figure>

La problématique de chargement des images réside dans la consommation de bande passante dès le chargement de la page, ce qui peut être inutile si le visiteur ne parcoure pas l’intégralité de la page. Les solutions permettant de palier ceci utilisent JavaScript, par exemple [bLazy](http://dinbror.dk/blog/blazy/) qui donne l’intégration suivante :

    :::html
    <figure>
        <img class="b-lazy"
            src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
            data-src="image.jpg"
            alt="Texte décrivant l'image">
        <noscript>
            <img src="image.jpg" alt="Texte décrivant l'image" />
        </noscript>
        <figcaption>Souvenez-vous du bon temps !</figcaption>
    </figure>

Une classe `b-lazy` est ajoutée, une image par défaut (ici un gif transparent très petit) est intégrée dans l’attribut `src` et l’`URL` vers la véritable image utilise un attribut `data-` permettant de stocker des données de manière standardisée. Pour les navigateur n’utilisant pas JavaScript, l’image est aussi proposée dans une balise `<noscript>` de manière classique.

    :::html
    <script src="blazy.min.js"></script>
    <script>
        ;(function() {
            var bLazy = new Blazy();
        })();
    </script>

On n’oublie pas ensuite d’importer le script et de l’initialiser dans la page. Beaucoup d’options existent pour gérer notamment le moment où est téléchargée l’image ainsi que la possibilité d’avoir une image pour les écrans à haute résolution.

La contrepartie d’une telle pratique (il existe [d’autres](https://vvo.github.io/lazyload/) [bibliothèques](https://afarkas.github.io/lazysizes/) pour le même résultat), c’est que l’internaute ne va pas pré-charger les images pour pouvoir les visionner ultérieurement (par exemple dans le train). Ce serait plus intéressant que cela soit une option au niveau du navigateur pour laisser ce choix entre les mains de l’utilisateur mais c’est un débat pour une autre fois.

Certaines bibliothèques permettent de gérer les différences de résolutions et de densité de pixels, sachant que l’on pourra le [faire nativement](http://responsiveimages.org/) sous peu, et avec [une béquille](http://scottjehl.github.io/picturefill/) dès maintenant. On a aussi discuté de [la différence](http://www.smashingmagazine.com/2014/05/responsive-images-done-right-guide-picture-srcset/) ([cache](/david/cache/0223c2efd811be0c22cec3a29bacc3e8/)) entre `picture` + `source` et `img` + `srcset`.

Il a enfin été question de `SVG` pour pouvoir avoir des images/graphes/logos vectorisés. Il y a plusieurs façon de [l’intégrer et de le styler](http://www.alsacreations.com/tuto/lire/1421-svg-initiation-syntaxe-outils.html) ([cache](/david/cache/5a64a81a55d0b585485a573bbfd8a01c/)) en `CSS`. La base est de savoir qu’il y a des formes dont on peut changer la couleur et la bordure, auxquelles ont peut appliquer [des filtres et des animations](https://css-tricks.com/using-svg/) ([cache](/david/cache/57cc77b47827e33de0f3a599449e5cc6/)). Il existe aussi [des outils](http://petercollingridge.appspot.com/) permettant de réduire la taille des `SVG` générés.

Au final, j’hésite encore à intégrer du *lazyloading* sur ce site bien que l’image des articles ne soit pas visible initialement mais j’ai peu d’images, c’est peut-être quelque chose à mettre en place pour les articles en caches pour soulager les producteurs par contre. En parallèle, je vais essayer d’utiliser les dernières techniques disponibles pour faire la distinction entre les résolutions mais ça ajoute du travail en amont (découpage/redimensionnement des images, compression différente, etc). **Le développement web est un éternel compromis.**
