❤ 9 octobre 2018 Choisir les dimensions des images responsives pour optimiser la webperf

Nicolas Hoizey Co-fondateur, directeur de l’innovation @nhoizey @[email protected]

Les images responsives

srcset-x Beau Soleil Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Beau Soleil Menu Menu Menu Beau Soleil Menu Menu Menu Menu Menu Menu Menu Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit Lorem ipsum dolor sit Lorem ipsum dolor sit Largeur d’image fixe et densité d’écran variable <img src="…" alt="…" srcset="image.jpg 1x, image-2x.jpg 2x"> 4

srcset-w Beau Soleil Bannière Beau Soleil Menu Menu Menu Beau Soleil Menu Menu Menu Menu Menu Menu Menu Bannière Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Largeur d’image variable, pleine largeur, et densité d’écran variable <img src="…" alt="…" srcset="image-640.jpg 640w, image-1024.jpg 1024w"> 5

srcset-w et sizes Beau Soleil Bannière Beau Soleil Menu Menu Menu Beau Soleil Menu Menu Menu Menu Menu Menu Menu Bannière Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Largeur d’image variable, différente selon breakpoints, et densité d’écran variable <img src="…" alt="…" srcset="image-640.jpg 640w, image-1024.jpg 1024w" sizes="(min-width: 1280px) 400px, (min-width: 640px) 60vw, 100vw"> 6

picture, source, srcset-w et sizes Beau Soleil Bannière Lorem ipsum dolor Beau Soleil Menu Menu Menu Beau Soleil Menu Menu Menu Menu Menu Menu Menu Bannière Lorem ipsum dolor Lorem ipsum dolor sit amet, consectetur Bannière Lorem ipsum dolor Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis odio dui, varius ac enim quis, accumsan porta nulla. Sed laoreet nibh sit amet lobortis porta. Donec sagittis est a tortor varius consectetur. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis odio dui, varius ac enim quis, accumsan porta nulla. Sed laoreet nibh sit amet lobortis porta. Donec sagittis est a tortor varius consectetur. Praesent sit amet sollicitudin mauris, non bibendum ante. Integer imperdiet in magna ac elementum. Sed arcu nibh, mattis ac tortor ultricies, consequat varius odio. Morbi at nunc at dolor auctor imperdiet in sit amet tortor. Largeur variable, contenu ou ratio different selon breakpoints, et densité variable <picture> <source media=”(max-width: 1280px)" srcset="…" sizes="100vw"> <img src="…" alt="…" srcset="…" sizes="500px"> </picture> 7

sizes décrit le layout

Côté CSS Beau Soleil Bannière Beau Soleil Menu Menu Menu Beau Soleil Menu Menu Menu Menu Menu Menu Menu Bannière Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. @media (min-width: 640px) { .card img { width: 60vw; } } Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. @media (min-width: 1280px) { .card img { width: 400px; } } 9

Lien entre CSS et sizes Beau Soleil Bannière Beau Soleil Menu Menu Menu Beau Soleil Menu Menu Menu Menu Menu Menu Menu Bannière Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. @media (min-width: 640px) { .card img { width: 60vw; } } Lorem ipsum dolor sit amet, consectet adipiscing elit. Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. <img src="…" alt="…" srcset="image-640.jpg 640w, image-1024.jpg 1024w" sizes="(min-width: 1280px) 400px, (min-width: 640px) 60vw, 100vw"> 10

srcset liste les images disponibles

Quelle dimensions dans srcset ? Les dimensions ne sont pas dictées par le layout/design Toutes les images n’occupent pas le même espace dans les pages Comment décider quelles dimensions prévoir ? <img src="…" alt="…" srcset="image-???.jpg ???w, image-???.jpg ???w" sizes="…"> 12

Les dimensions attendues Proportion de vues Images attendues Largeur d’image

Fournir les images aux dimensions exactement attendues

Les dimensions attendues Proportion de vues Images attendues Largeur d’image

Des dimensions exactes Proportion de vues Images attendues Images servies Largeur d’image

Des dimensions exactes Demander au serveur une image aux dimensions exactes nécessaires pour l’affichage : ● Le meilleur moyen d’éviter le gaspillage de bande passante et de ! ressources côté navigateur 17

Des dimensions exactes Demander au serveur une image aux dimensions exactes nécessaires pour l’affichage : ☹ Impossible de mettre toutes les dimensions dans le srcset du HTML fourni par le serveur ○ ○ ○ Donc nécessite JavaScript Donc retarde le chargement Donc utilisable uniquement en cas de lazy-loading 18

Des dimensions exactes pour le lazy-load Même pour le lazy-load, des dimensions exactes impliquent : ● Soit une génération à la volée systématique ! ○ Donc une latence supplémentaire de traitement côté serveur ○ Et potentiellement une compression moins forte faute de temps de calcul ! Soit un système de cache des images aux bonnes dimensions ○ Donc une capacité de stockage faramineuse ○ Ou des approximations de dimensions par paliers 19

Les breakpoints d’images

Les breakpoints d’images Jason Grigsby (Cloudfour) évoque la notion de breakpoints d’images https://cloudfour.com/thinks/responsive-images-101-part-9-image-breakpoints/ 21

Le budget de performance

Le budget de performance Le budget de performance défini un écart de poids ∆ à ne pas dépasser entre deux dimensions consécutives 23

Responsive Image Breakpoints Generator Un outil développé par Cloudinary suite aux billets de Jason Grigsby, et disponible via une interface ou via l’API : http://www.responsivebreakpoints.com/ Paramètres : • • • • Différence de poids ∆ entre variantes Nombre total d’images Prise en compte de la densité x2 Direction Artistique 24

Responsive Image Breakpoints Generator 25

Responsive Image Breakpoints Generator 26

Les dimensions attendues Proportion de vues Images attendues Largeur d’image

Le budget de performance Proportion de vues Images attendues Images servies Largeur d’image

Le budget de performance Proportion de vues ? Images attendues Images servies « gaspillage » Largeur d’image

Le budget de performance Un écart de poids ∆ à ne pas dépasser entre deux dimensions consécutives : ● S’il y a peu d’images, le navigateur ne télécharge pas beaucoup plus ! que nécessaire 30

Le budget de performance Un écart de poids ∆ à ne pas dépasser entre deux dimensions consécutives : ☹ Les calculs de paliers doivent être fait individuellement pour chaque image, et non pour chaque emplacement ☹ Certaines tailles calculées peuvent s’avérer inutiles ☹ Surcharge non négligeable si la page a beaucoup d’images, et qu’il faut télécharger ∆ en trop, pour chacune, pour des viewport et densité donnés 31

Les requêtes les plus fréquentes

Les requêtes les plus fréquentes Limiter : • Les écarts de poids entre images attendues et fournies • Le nombre d’images à générer/stocker Nécessite des données statistiques, et des calculs complexes. 33

Les dimensions attendues Proportion de vues Images attendues Largeur d’image

Les requêtes les plus fréquentes Proportion de vues Images attendues Images servies Largeur d’image

Les requêtes les plus fréquentes Proportion de vues Images attendues Images servies « gaspillage » Largeur d’image

Étape 1 : statistiques des visiteurs

Collecter les statistiques de viewports et densité d’écran des visiteurs pendant quelque temps

Étape 1 : statistiques des visiteurs

From https://gist.github.com/nhoizey/a993b1f8e0263bd2ef83e78a4378bbb1

// get device pixel ratio in dppx
var screen_density =
  typeof window == 'undefined’
    ? 0
    : +window.devicePixelRatio ||
      Math.sqrt(screen.deviceXDPI * screen.deviceYDPI) / 96 || 0
// keep only 3 decimals
screen_density = +(Math.round(screen_density + 'e+3') + 'e-3')

// get viewport width
var viewport_width = Math.max(
  document.documentElement.clientWidth,
  window.innerWidth || 0,
)

Étape 2 : largeur d’image selon viewports

Déterminer la variation de la largeur d’image selon les viewports

Étape 3 : consolider les données

  1. Pour chaque couple viewport/densité des statistiques visiteurs, associer :
  • Largeur d’image nécessaire = largeur d’image CSS (à ce viewport) * densité
  • Nombre de pages vues
  1. Grouper par largeurs d’image identiques
  2. Transformer en pourcentages

Étape 4 : identifier les valeurs cibles

Tester l’impact du choix simple des valeurs les plus courantes.

Étape 5 : finaliser le choix

Assurer un faible écart entre valeurs retenues et valeurs réelles

Étape 5 : finaliser le choix

Les requêtes les plus fréquentes

Limiter les écarts de poids entre images attendues et fournies :

  • 😃 Quel que soit le nombre d’images, le navigateur ne télécharge pas (beaucoup) plus que nécessaire
  • 😃 Les calculs sont fait par emplacement et non image par image

Les requêtes les plus fréquentes

Limiter les écarts de poids entre images attendues et fournies :

  • ☹ Les calculs sont laborieux
  • ☹ Il faut les refaire régulièrement, pour prendre en compte les changements de statistiques

Automatiser

La courbe théorique d'un projet d'automatisation : https://xkcd.com/1319/

responsive-images-widths

Un projet Node.js open source disponible sur Github : https://github.com/cleverage/responsive-image-sizes

Opérationnel :

  • Prendre en entrée un fichier CSV de statistiques
  • Déterminer la largeur d’une image selon les viewports avec Puppeteer
  • Consolider toutes ces données

responsive-images-widths

Screenshot d'une exécution du script dans un terminal

responsive-images-widths

À finaliser :

  • Déterminer les valeurs optimales par clustering (algorithme de partitionnement de données type k-means ou de machine learning)
  • Prendre en charge toutes les images d’une page en une fois
  • Automatiser l’intégration à un workflow de développement

Automatiser

Statut du projet sur la courbe théorique d'avancement du projet : https://xkcd.com/1319/

Automatiser

La réalité des projets d'automatisation : https://xkcd.com/1319/

Were we're going, we need perf

Le sticker de Clever Age avec la DeLorean de Retour Vers Le Futur