$30 off During Our Annual Pro Sale. View Details »

Tu fais du Web et tu ne connais pas les Layout Shifts ?! Nan mais...

Raphael Goetter
October 05, 2022

Tu fais du Web et tu ne connais pas les Layout Shifts ?! Nan mais...

Les "Cumulative Layout Shifts" seraient-ils un problème majeur selon Google et pourtant... méconnu de la plupart des intégrateurs et intégratrices ?

La préoccupation consistant à "Réduire les Layout Shifts" couvre une large palette de domaines du Web dont l'UX, HTML, CSS, la Performance, voire le Référencement.

Voyons donc comment s'y prendre pour atténuer ces comportements néfastes (surtout du côté CSS parce que c'est le plus impactant et que c'est ce que je connais le mieux !).

Raphael Goetter

October 05, 2022
Tweet

More Decks by Raphael Goetter

Other Decks in Design

Transcript

  1. Layout Shifts Tu fais du Web et tu connais pas

    les ? Et surtout : pourquoi personne ne comprend de quoi je parle et n'ose me le dire ? Nan mais... 📞 1
  2. Hello ! Je suis Raphaël... raphaël goetter 2

  3. Depuis 2003 Un forum, des tutos, un service d'emploi Opensource

    et gratuit 30000 visiteurs / jour 50000 membres sur le forum .com Communauté d'apprentissage 3
  4. .fr Depuis 2006 On fait des sites web performants et

    accessibles On dispense des formations On est une petite équipe de 10 personnes On a un peu l’accent alsacien Agence web, organisme de formation 4
  5. À L'AFFICHE 5

  6. Layout Shifts “ Ce sont l'ensemble des repositionnements, redimensionnements, décalages

    intempestifs des contenus pendant la durée de vie d'une page Web... mais "Layout Shifts" c'est quand-même vachement plus court comme titre. OK, alors c'est quoi des ? 6
  7. https://web.dev/cls/ Mouais c'est pas clair tout ça, tu me montres

    ? spoiler alert : le design de la page change au moment de l'interaction avec le visiteur 7
  8. Le Cumulative Layout Shift (CLS) est une métrique introduite en

    2020 par . Elle mesure la quantité de contenu qui se déplace durant l'affichage de la page, ainsi que la distance de déplacement. Google Lighthouse Pourquoi c'est important ? Le CLS est considéré par Google comme l’un des critères UX essentiels au bon fonctionnement d’un site web. 8
  9. Le Cumulative Layout Shift fait partie des Core Web Vitals.

    Google a annoncé utiliser les Core Web Vitals (Page Experience) comme signal de ranking dès 2021. 🤯 source : https://www.dareboost.com 9
  10. “ Ce sujet à lui seul couvre les thèmes :

    UX, HTML, CSS, Performance... et SEO Cumulative Layout Shifts 10
  11. Outils Commençons par les trucs bien sympas pour détecter les

    Layout Shifts sur une page 11
  12. Outils en ligne (et en plus c'est français !) https://www.dareboost.com

    (de notre ami Google) https://pagespeed.web.dev/ (le plus complet à ce jour) https://www.webpagetest.org/ 12
  13. webpagetest les CLS vus en "Filmstrip" https://www.webpagetest.org/video/compare.php?tests=221005_AiDcMR_5GJ-r:1- c:0&highlightCLS=1 13

  14. Outils en local (opensource, multibrowsers) Lighthouse (opensoure, multibrowsers) Chrome DevTools

    (extension Firefox et Edge) SpeedVitals (extension Chrome) Web Vitals 14
  15. > Chrome Devtools > Ctrl + Maj + P >

    "Rendering" > Layout Shift Regions 15
  16. Bon, du coup, comment on évite ces Layout Shifts ?

    Réserver l'espace pour les publicités ou les iframes Diminuer le nombre de contenus injectés dynamiquement Construire des pages en préférant des zones de tailles fixes, non déterminées par leur contenu Indiquer largeur et hauteur des images et vidéos Précharger les polices pour éviter les comportements FOIT ou FOUT Éviter les animations sans transform et translate 16
  17. Layout Shifts dûs aux animations 1 17

  18. img { margin-left: 0; transition: 0.5s; } img:hover { margin-left:

    100px; } ooh la jolie transition ! 18
  19. img { margin-left: 0; transition: 0.5s; } img:hover { margin-left:

    100px; } ooh la jolie transition ! 19
  20. img { margin-left: 0; transition: 0.5s; } img:hover { margin-left:

    100px; } ooh la jolie transition ! @keyframes pika { to { position: absolute; left: 100px; } } img:hover { animation: pika 0.5s; } ooh la belle animation ! 👎 20
  21. animation et perfs margin padding width position top, right, bottom,

    left display font-* visibility box-shadow transform opacity color background border text-shadow z-index 21
  22. animation et perfs margin padding width position top, right, bottom,

    left display font-* visibility box-shadow transform opacity color background border text-shadow z-index Propriétés qui agissent sur Style, Layout ou Paint. Le navigateur doit redessiner et recomposer la page. Propriétés qui n'agissent que sur la Composition 22
  23. Solution 1 : Animer de préférence les propriétés dites "composites"

    (transform, translate, opacity) Solution 2 : si la solution 1 n'est pas envisageable, appliquer la propriété will-change ou (hack) translateZ Conclusion Layout Shift dûs aux transitions et animations 23
  24. Layout Shifts dûs à la mise en page 2 24

  25. https://http203-playlist.netlify.app/videos/avoiding-layout-shift-by-putting-the-css-in-charge/ Avoiding layout shift by putting the CSS in charge

    25
  26. cas concret trois colonnes 26

  27. .container { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 1rem;

    } 1 2 3 4 5 méthode 1 .container { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 1rem; } 1 2 3 4 5 6 méthode 2 27
  28. méthode 1 grid-template-columns .container { display: grid; grid-template-columns: 1fr 1fr

    1fr; gap: 1rem; } 1 2 3 4 5 je suis le temps qui passe... layout shift 28
  29. méthode 2 grid-auto-flow .container { display: grid; grid-auto-flow: column; grid-auto-columns:

    1fr; gap: 1rem; } 1 2 3 4 5 6 je suis le temps qui passe... layout shift layout shift layout shift layout shift 29
  30. "auto" min-content max-content fit-content 1fr flex-shrink flex-grow stretch min-width: auto

    width: auto valeur connue par le navigateur que lorsque tous les contenus (texte, polices, images, médias) sont chargés et dimensionnés 30
  31. Flexbox Grid Layout Conçu pour s'adapter aux contenus. = Plus

    sensible aux Layout Shifts Flexbox est designé pour être fluide par défaut. Conçu pour englober les contenus. = Moins sensible aux Layout Shifts 💪 Grid Layout est designé pour être rigide par défaut. 31
  32. #old... mais... https://jakearchibald.com/2014/dont-use-flexbox-for-page-layout/ 32

  33. QUIZ ! alors c'est quoi le mieux ? 33

  34. .container { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; } 1

    2 3 4 5 .container { display: grid; grid-template-columns: 1fr 1fr 1fr; } 1 2 3 4 1 2 on vient d'en parler il y a 5min, faut suivre un peu... 34
  35. .flex-item { flex-grow: 1; } 1 2 3 .flex-item {

    flex: 1; } 1 2 3 1 2 = flex-grow: 1 & flex-basis: 0 = flex-grow: 1 & flex-basis: auto 35
  36. .flex-item { flex: 1; } 1 2 3 .flex-item {

    flex: 1 0 0; } 1 2 3 1 2 = flex-grow: 1 & flex-shrink: 1 36
  37. .flex-item { flex: 1; } 1 2 3 .flex-item {

    flex: 1; min-width: 0; } 1 2 3 4 1 2 par défaut min-width vaut "auto" sur un flex item 37
  38. .container { display: grid; grid-template-columns: 1fr 1fr; } 1 2

    3 4 .container { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); } 1 2 3 4 1 2 1fr = minmax(min-content, 1fr) 38
  39. .container { display: grid; grid-template-columns: repeat(auto-fill, 100px); } 1 2

    3 4 .container { display: grid; grid-template-columns: repeat(auto-fit, 100px); } 1 2 3 4 1 2 auto-fit supprime les colonnes inutiles quand elles sont vides de contenu 39
  40. Utilisez Grid Layout en priorité tant que possible, et Flexbox

    si nécessaire. Tentez de limiter les valeurs automatiques, dépendantes du contenu. Si vous utilisez un framework, jetez un oeil sous le capot Conclusion Layout Shifts dûs à la mise en page par ex. dans Bootstrap un élément en .col-6 vaudra flex: 0 0 auto; width: 50%; 40
  41. Layout Shifts dûs aux médias 3 41

  42. <img src="(chemin)" alt=""> <p>Lorem Elsass...</p> 1 2 Lorem Elsass Ipsum

    mitt picon bière munster du ftomi! Ponchour bisame. Bibbeleskaas jetz rossbolla sech choucroute un schwanz geburtstàg, Chinette dû, ìch bier deppfele schiesser. Flammekueche de knèkes Seppele gal! a hopla geburtstàg, alles fraü Chulia Roberts oder knäckes dûû blottkopf. Noch bredele schissabibala, yeuh e schmutz. largeur du parent : 200px 1 on dirait bien que l'image n'est pas encore chargée... suspense... il semble que je souhaite afficher une image... 42
  43. <img src="(chemin)" alt=""> 1 Lorem Elsass Ipsum mitt picon bière

    munster du ftomi! Ponchour bisame. Bibbeleskaas jetz rossbolla sech choucroute un schwanz geburtstàg, Chinette dû, ìch bier deppfele schiesser. Flammekueche de knèkes Seppele gal! a hopla geburtstàg, alles fraü Chulia Roberts oder knäckes dûû blottkopf. Noch bredele schissabibala, yeuh e schmutz. image 200 x 100px largeur du parent : 200px l'image est chargée, elle crée un Layout Shift 1 43
  44. <img src="(chemin)" alt="" width="200" height="100"> 1 Lorem Elsass Ipsum mitt

    picon bière munster du ftomi! Ponchour bisame. Bibbeleskaas jetz rossbolla sech choucroute un schwanz geburtstàg, Chinette dû, ìch bier deppfele schiesser. Flammekueche de knèkes Seppele gal! a hopla geburtstàg, alles fraü Chulia Roberts oder knäckes dûû blottkopf. Noch bredele schissabibala, yeuh e schmutz. largeur du parent : 200px l'espace est réservé avant même que l'image ne soit chargée 2 44
  45. <img src="(chemin)" alt="" width="200" height="100"> 1 Lorem Elsass Ipsum mitt

    picon bière munster du ftomi! Ponchour bisame. Bibbeleskaas jetz rossbolla sech choucroute un schwanz geburtstàg, Chinette dû, ìch bier deppfele schiesser. Flammekueche de knèkes Seppele gal! a hopla geburtstàg, alles fraü Chulia Roberts oder knäckes dûû blottkopf. Noch bredele schissabibala, yeuh e schmutz. image 200 x 100px largeur du parent : 200px et hop, pas de Layout Shift ! 2 bah c'est bien beau mais moi je fais du Responsive et ma taille d'image au départ est variable, mettons 2000x1000 tiens ! 45
  46. <img src="(chemin)" alt="" width="2000" height="1000"> 1 image 2000 x 1000px

    largeur du parent : 200px bah forcément ça déborde ! 3 46
  47. <img src="(chemin)" alt="" width="2000" height="1000"> 1 largeur du parent :

    200px 3 img { max-width: 100%; } 1 2 3 tu es bien taquin ! ça rentre en largeur mais c'est tout déformé verticalement 47
  48. img { max-width: 100%; height: auto; } 1 2 3

    4 Lorem Elsass Ipsum mitt picon bière munster du ftomi! Ponchour bisame. Bibbeleskaas jetz rossbolla sech choucroute un schwanz geburtstàg, Chinette dû, ìch bier deppfele schiesser. Flammekueche de knèkes Seppele gal! a hopla geburtstàg, alles fraü Chulia Roberts oder knäckes dûû blottkopf. Noch bredele schissabibala, yeuh e schmutz. largeur du parent : 200px l'espace est réservé avant même que l'image ne soit chargée 4 <img src="(chemin)" alt="" width="2000" height="1000"> 1 48
  49. img { max-width: 100%; height: auto; } 1 2 3

    4 <img src="(chemin)" alt="" width="2000" height="1000"> 1 Lorem Elsass Ipsum mitt picon bière munster du ftomi! Ponchour bisame. Bibbeleskaas jetz rossbolla sech choucroute un schwanz geburtstàg, Chinette dû, ìch bier deppfele schiesser. Flammekueche de knèkes Seppele gal! a hopla geburtstàg, alles fraü Chulia Roberts oder knäckes dûû blottkopf. Noch bredele schissabibala, yeuh e schmutz. image 2000 x 1000px largeur du parent : 200px et hop, pas de Layout Shift ! 4 height: auto permet au navigateur d'appliquer le ratio de l'image quelle que soit sa largeur d'affichage ! width et height indiquent au navigateur le ratio de l'image 49
  50. <img src="(chemin)" alt="" width="2000" height="1000"> 1 Lorem Elsass Ipsum mitt

    picon bière munster du ftomi! Ponchour bisame. Bibbeleskaas jetz rossbolla sech choucroute un schwanz geburtstàg, Chinette dû, ìch bier deppfele schiesser. Flammekueche de knèkes Seppele gal! a hopla geburtstàg, alles fraü Chulia Roberts oder knäckes dûû blottkopf. Noch bredele schissabibala, yeuh e schmutz. largeur du parent : 200px 4 la couleur de fond de l'image s'applique même quand l'image n'est pas chargée, couvrant la surface de l'image grâce à son ratio connu du navigateur img { max-width: 100%; height: auto; background: gray; } 1 2 3 4 5 chouette astuce ! 50
  51. Indiquer les dimensions (width et height) dans le HTML pour

    que le navigateur puisse calculer le ratio. Utiliser des formats d'images modernes (webp, avif) max-width: 100% pour que l'image s'adapte en largeur à son conteneur. height: auto pour que le navigateur applique le ratio systématiquement background-color sur l'image pour indiquer visuellement l'espace qui sera occupé quand elle sera chargée (placeholder). Conclusion Layout Shift dûs aux médias 51
  52. tu veux test ? https://codepen.io/raphaelgoetter/pen/MWVmXjM 52

  53. Layout Shift des Polices 4 53

  54. 54

  55. .woff et formats compressés 55

  56. 56

  57. @font-face { font-family: kiwi; src: url("/fonts/kiwi.woff2") format("woff2"); } 💪 57

  58. font-display 58

  59. body { font-family: SuperPolice, arial, sans-serif; } 1 2 3

    @font-face { font-family: SuperPolice; src: url("superfont.woff2") format("woff2"); } 1 2 3 4 5 font-display: swap; transparent arial SuperPolice 59
  60. police alternative "en attendant" police invisible "en attendant" swap block

    60
  61. auto font-display: auto; @font-face { 1 font-family: kiwi; 2 src:

    url("kiwi.woff2"); 3 4 } 5 Valeur par défaut. Le navigateur décide de sa stratégie d'affichage : FOUT, FOIT, autre, bref il fait sa vie quand utiliser "auto" ? Jamais ? A priori aucun intérêt d'avoir des comportements différents selon les navigateurs. 61
  62. block font-display: block; @font-face { 1 font-family: kiwi; 2 src:

    url("kiwi.woff2"); 3 4 } 5 Bloquage volontaire de la police durant 3s. Le contenu est alors invisible, c'est le FOIT. quand utiliser "block" ? Adapté pour les fontes d'icônes, pour éviter les caractères exotiques quand la police n'est pas encore chargée. 62
  63. 63

  64. swap font-display: swap; @font-face { 1 font-family: kiwi; 2 src:

    url("kiwi.woff2"); 3 4 } 5 Affichage immédiat de la police alternative, puis remplacement quand la police est chargée. C'est le FOUT. quand utiliser "swap" ? Adapté pour tous les contenus textuels mais déclenche forcément un Layout Shift. 64
  65. fallback font-display: fallback; @font-face { 1 font-family: kiwi; 2 src:

    url("kiwi.woff2"); 3 4 } 5 Comportement un peu passe-partout. On cumule FOIT puis FOUT. quand utiliser "fallback" ? 65
  66. optional font-display: optional; @font-face { 1 font-family: kiwi; 2 src:

    url("kiwi.woff2"); 3 4 } 5 La police n'est affichée que si elle est immédiatement disponible (déjà dans le cache par exemple). BONUS : elle sera affichée sur la page suivante. quand utiliser "optional" ? Parfait si la police n'est pas absolument nécessaire ou si elle est pré-chargée. Ne crée pas de Layout Shift. 💪 66
  67. font-display compatibilité https://caniuse.com/css-font-rendering-controls 67

  68. Police alternative ajustée 68

  69. https://screenspan.net/fallback 69

  70. @font-face { font-family: 'Adjusted FredokaOne-Regular'; src: url(FredokaOne-Regular.woff2) format('woff2'); size-adjust: 98%;

    ascent-override: 72%; descent-override: 5%; line-gap-override: 41%; font-display: swap; } h1 { font-family: 'Adjusted FredokaOne-Regular', 'Arial'; } 1 2 3 4 5 6 7 8 9 10 11 12 13 Police principale ajustée 70
  71. @font-face { font-family: 'Adjusted Arial Fallback'; src: local(Arial); size-adjust: 108%;

    ascent-override: 72%; descent-override: 0%; line-gap-override: 41%; } h1 { font-family: 'FredokaOne-Regular', 'Adjusted Arial Fallback'; } 1 2 3 4 5 6 7 8 9 10 11 12 Police alternative ajustée 71
  72. size-adjust compatibilité https://caniuse.com/mdn-css_at-rules_font-face_size-adjust 72

  73. Préchargement 73

  74. Préchargement avec rel=preload https://web.dev/priority-hints/ <!-- Dans le <head> après la

    feuille de styles pour ne pas la bloquer --> <link rel="preload" as="font" href="kiwi.woff2" type="font/woff2" crossorigin="anonymous"> Prévu pour plein de ressources : surtout fonts et images, mais aussi style, script, audio, vidéo, embed, object, etc 74
  75. sans rel="preload" HTML CSS font 1 font 2 FOUT /

    FOIT je suis le temps qui passe... 75
  76. avec rel="preload" HTML CSS font 1 font 2 FOUT /

    FOIT je suis le temps qui passe... 76
  77. Compresser les fichiers (.woff2) Choisir font-display: optional Éviter les icon-fonts

    Ajustez les polices alternatives Précharger les polices critiques Héberger les polices sur son propre domaine Conclusion Layout Shifts des polices web 77
  78. Ressources 78

  79. The Almost-Complete Guide to Cumulative Layout Shift https://jessbpeck.com/posts/completecls/ 79

  80. Optimizing Web Vitals using Lighthouse https://web.dev/optimize-vitals-lighthouse/ 80

  81. CLS et impact sur le SEO https://fr.oncrawl.com/seo-technique/quest-ce-que-le-cumulative-layout-shift/ 81

  82. CLS et WordPress https://wp-rocket.me/how-to-improve-cls-on-wordpress/ 82

  83. Merci ! Slides sur speakerdeck.com/goetter 83