1. 3 astuces pour des performances mobiles de l’extrême

    Fin-mai 2012 j’ai rejoint l’équipe Responsive News de la British Broadcasting Corporation. Il s’agit d’un projet pionnier dans le monde du journalisme en ligne : pour la première fois, une énorme compagnie dans le secteur des media adopte une politique réellement “mobile first” dans la création d’un site dédié aux mobiles, smartphones et tablettes.

    Le site Responsive News testé sous toutes les coutures

    Contrairement certains acteurs ayant implémenté le Responsive Web Design (Boston Globe par exemple), BBC News propose une solution partiellement adaptative, séparant le monde mobile/tablette du monde de l’ordinateur de bureau. Se soucier des mobiles, smartphones et tablettes uniquement nous a permis de mieux concentrer nos efforts sur un aspect crucial du produit : la performance.

    Petit rappel de quelques raisons pour lesquelles la performance d’un site web est importante sur mobile :

    • un coût des données sur mobile très élevé
    • un faible débit et une (souvent) faible qualité de la connexion
    • un matériel peu puissant, notamment dans les pays en voie de développement et certaines classes sociales
    • une durée de vie limitée de la batterie
    • et enfin, une attente des visiteurs qui souhaitent de meilleures performances sur mobile que sur desktop

    À ma connaissance, aucun autre site d’actualité ne prend autant au sérieux la performance en responsive web design, ce qui est bien dommage mais pas étonnant compte tenu du temps que cela prend à développer (et donc de l’argent que cela coûte à la compagnie).

    Je ne ferai pas un compte rendu des techniques d’optimisation sur mobile les plus connues, que vous pourrez retrouver dans cette excellente présentation de Sam Dutton à la conférence Velocity 2012.

    Ce billet dévoile des techniques qui s’appliquent dans le cadre du projet Responsive News, et peuvent s’adapter dans certains contextes uniquement, selon notre credo : tester, mesurer, puis améliorer.

    1. Styles : ne charger que le nécessaire

    Par défaut, nous chargeons les styles basés sur notre plus petit dénominateur commun (pour le vieux Nokia de votre maman par exemple), puis nous augmentons l’expérience pour les navigateurs plus modernes (smartphones, tablettes…) en chargeant de nouvelles de feuilles de style.

    Ainsi, un utilisateur qui visite le site à l’aide d’un mobile âgé et/ou d’un navigateur de type Opera Mini aura une expérience de navigation extrêmement rapide, constituée d’un minimum d’images et d’une présentation sommaire mais fonctionnelle.

    Enfin, si le navigateur utilisé est assez moderne pour supporter la “version améliorée” du site, nous détectons la taille du viewport puis chargeons uniquement la ou les CSS qui vont servir à l’utilisateur. La méthode vient aussi pallier le fait que les navigateurs téléchargent tous les fichiers CSS référencés dans <head>.

    Par exemple, une méthode (schématisée à l’extrême) de chargement des styles pour tablettes :

    <!-- CSS de base -->
    <link type="text/css" rel="stylesheet" href="core.css" />
    <script>
    // CSS pour tablettes
    if (largeur > 640 or hauteur > 640) {
        document.write('<link type="text/css" rel="stylesheet" href="tablet.css" />');
    }
    </script>

    Cette technique peut sembler contre-intuitive, mais elle permet de gagner jusqu’à 16 KB sur les feature phones, sachant que le poids total de la page (images et CSS compris) quand JavaScript est désactivé est de 25 KB. Le projet grossit de sprint en sprint (bientôt 27 langages supportés et de nombreuses nouvelles fonctionnalités), et nous pensons que cette technique va s’avérer de plus en plus bénéfique pour les performances au fur et à mesure de la croissance du projet.

    La maintenabilité du code CSS est assurée par une gestion des conditions en Sass (@if $core, @if $compact, @if tablet). La segmentation des fichiers entre la base et les feuilles de style additionnelles est donc gérée par le pré-processeur lui-même.

    Par ailleurs, nous avons choisi de ne pas inclure de styles d’impression (pour le moment), ce qui réduit encore le poids final des CSS.

    Tout sur la technique “Cutting the Mustard” sur le blog Responsive News

    2. Images : limiter le nombre et servir la taille adaptée

    Le W3C ne propose actuellement pas de standard concernant les images adaptatives. Il faut donc ruser avec du JavaScript en attendant une meilleure solution.

    Plusieurs points de friction à prendre en compte, et leur impact direct :

    • poids : bande passante
    • nombre : latence des requêtes HTTP
    • dimensions : taille du viewport

    Pour adapter la taille des images au viewport sans multiplier les requêtes HTTP, il est préférable d’utiliser un minimum de tags <img />.

    De nombreuses techniques existent pour charger des images en responsive web design (rien qu’au sein de la BBC, nous en dénombrons au moins 4). Dans notre cas, nous générons des vignettes à partir de l’original, de 96 à 736 pixels de large. Selon la taille du viewport, nous adaptons la source des images à charger.

    Quand une image est liée à un contenu, nous avons donc un élément “factice” dans le DOM :

    <div class="image-replace" data-src="source.jpg"></div>

    Si la taille du bloc se situe aux alentours de 240px de large, cette div sera remplacée en JavaScript par :

    <img src="source-240.jpg" alt="" />

    C’est en fait un poil plus compliqué que ça dans la réalité, mais cet exemple résume bien l’idée. À noter que nous n’appliquons cette technique qu’à des images provenant de la base de données fournie par les journalistes (le contenu des actualités). Les icônes et autres images composant l’interface sont traitées à part.

    Un gros travail de réécriture de notre module “imageEnhancer” est en cours pour encore améliorer le chargement des images :

    • éviter les doubles chargements (ex. : ne pas charger une image de moins bonne qualité si on a déjà chargé une version améliorée auparavant, ce qui peut survenir lors du changement d’orientation)
    • en projet : modifier la qualité selon le type de connexion (ex. : haute qualité en wifi & 3G, et basse qualité en edge)
    • à terme, proposer une version “Retina” des images du contenu si la connexion et l’écran le permettent

    3. JavaScript : séparer les besoins

    Dans notre fichier JavaScript concaténé (all.js - 23 K gzippé & minifié), deux types de modules cohabitaient :

    • modules critiques pour l’utilisabilité et la sensation de performance
    • modules d’amélioration progressive

    En prenant en compte que les navigateurs mobiles n’ont qu’un thread d’interprétation du code (même avec un processeur quad-core), une bande passante souvent limitée et une puissance de calcul faible (comparée à un ordinateur classique), nous avons décidé de placer les modules critiques pour l’utilisabilité directement en ligne dans le <head> du document.

    Nous avons donc exclu de all.js les composants suivants :

    • module de chargement des CSS
    • feature detection, comme le support de @font-face (impacte l’affichage de certains éléments graphiques)
    • masquage de la barre de navigation du navigateur (cf)

    Ces modules sont placés directement dans une balise <script></script> à l’intérieur du <head> et sont codés pour être aussi peu bloquants que possible, et exécutés très tôt dans la résolution du document.

    Ainsi, nous évitons les reflows, repaints et autres FOUC (Flash Of Unstyled Content) liés à un délai d’exécution du JavaScript. Je vous conseille d’ailleurs cet excellent article de Nicole Sullivan pour apprendre à éviter les reflows.

    Nous veillons tout de même à ce que ces scripts ne deviennent pas trop volumineux car ils ne sont pas cachables : si nous arrivons à 20 KB de scripts inline, cette technique deviendra au contraire un frein à la performance du site.

    Aller toujours plus loin

    Premièrement, oubliez tout ce que vous venez de lire car cela change tout le temps, et surtout, n’implémentez que ce que vous pouvez effectivement justifier comme étant une valeur ajoutée pour votre produit. Chaque site est différent, et dans la performance web, la réponse à la plupart des questions est “ça dépend”.

    De nombreuses pistes d’amélioration s’offrent à nous avec l’émergence de nouveaux standards du web, formats d’images (webp ?), et protocoles de communication (SPDY, HTTP2). En attendant nous essayons de faire de notre mieux avec les outils à notre disposition, ce qui explique pourquoi les techniques que nous mettons en place s’apparentent fortement à du hack.

    À noter que l’équipe de Responsive News tente de documenter l’avancement du développement de manière plus ou moins publique :

    Retrouvez sur Twitter les développeurs ayant donné naissance à ces techniques :

    Merci à Marie (@kReEsTaL) qui a posé une question sur le sujet et m’a inspiré ce billet.

Notes

  1. jiceb reblogged this from kaelig
  2. goetter reblogged this from kaelig
  3. kaelig posted this