Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

    View Slide

  2. Hello !
    Je suis Raphaël...
    raphaël goetter
    2

    View Slide

  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

    View Slide

  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

    View Slide

  5. À L'AFFICHE
    5

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  10. “ Ce sujet à lui seul couvre les thèmes :
    UX, HTML, CSS, Performance... et SEO
    Cumulative Layout Shifts
    10

    View Slide

  11. Outils
    Commençons par les trucs bien sympas pour
    détecter les Layout Shifts sur une page
    11

    View Slide

  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

    View Slide

  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

    View Slide

  14. Outils en local
    (opensource, multibrowsers)
    Lighthouse
    (opensoure, multibrowsers)
    Chrome DevTools
    (extension Firefox et Edge)
    SpeedVitals
    (extension Chrome)
    Web Vitals
    14

    View Slide

  15. > Chrome Devtools
    > Ctrl + Maj + P
    > "Rendering"
    > Layout Shift Regions 15

    View Slide

  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

    View Slide

  17. Layout Shifts dûs aux
    animations
    1
    17

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  24. Layout Shifts dûs à la mise en
    page
    2
    24

    View Slide

  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

    View Slide

  26. cas concret
    trois colonnes
    26

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  32. #old... mais...
    https://jakearchibald.com/2014/dont-use-flexbox-for-page-layout/ 32

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  41. Layout Shifts dûs aux médias
    3
    41

    View Slide


  42. Lorem Elsass...
    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

    View Slide


  43. 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

    View Slide

  44. 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

    View Slide

  45. 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

    View Slide

  46. width="2000" height="1000">
    1
    image
    2000 x 1000px
    largeur du parent : 200px
    bah forcément ça déborde !
    3
    46

    View Slide

  47. 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

    View Slide

  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 width="2000" height="1000">
    1
    48

    View Slide

  49. img {
    max-width: 100%;
    height: auto;
    }
    1
    2
    3
    4
    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

    View Slide

  50. 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

    View Slide

  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

    View Slide

  52. tu veux test ?
    https://codepen.io/raphaelgoetter/pen/MWVmXjM 52

    View Slide

  53. Layout Shift des Polices
    4
    53

    View Slide

  54. 54

    View Slide

  55. .woff
    et formats compressés
    55

    View Slide

  56. 56

    View Slide

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

    View Slide

  58. font-display
    58

    View Slide

  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

    View Slide

  60. police alternative "en attendant"
    police invisible "en attendant"
    swap
    block
    60

    View Slide

  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

    View Slide

  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

    View Slide

  63. 63

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  67. font-display
    compatibilité
    https://caniuse.com/css-font-rendering-controls
    67

    View Slide

  68. Police alternative
    ajustée
    68

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  72. size-adjust
    compatibilité
    https://caniuse.com/mdn-css_at-rules_font-face_size-adjust
    72

    View Slide

  73. Préchargement
    73

    View Slide

  74. Préchargement
    avec rel=preload
    https://web.dev/priority-hints/

    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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  78. Ressources
    78

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide