Tutoriel sur l'utilisation de WebPageTest pour identifier et résoudre les problèmes d'instabilité de la mise en page.
Dans un article précédent, j'ai expliqué comment mesurer le CLS (Cumulative Layout Shift) dans WebPageTest. Le CLS est une agrégation de tous les décalages de mise en page. Dans cet article, j'ai donc pensé qu'il serait intéressant d'aller plus loin et d'inspecter chaque décalage de mise en page sur une page pour essayer de comprendre ce qui pourrait être à l'origine de l'instabilité et de résoudre le ou les problèmes.
Mesurer les décalages de mise en page
L'API Layout Instability permet d'obtenir la liste de tous les événements de décalage de mise en page d'une page:
new Promise(resolve => {
new PerformanceObserver(list => {
resolve(list.getEntries().filter(entry => !entry.hadRecentInput));
}).observe({type: "layout-shift", buffered: true});
}).then(console.log);
Cela génère un tableau de décalages de mise en page qui ne sont pas précédés d'événements d'entrée:
[
{
"name": "",
"entryType": "layout-shift",
"startTime": 210.78500000294298,
"duration": 0,
"value": 0.0001045969445437389,
"hadRecentInput": false,
"lastInputTime": 0
}
]
Dans cet exemple, il n'y a eu qu'un très léger décalage de 0,01% à 210 ms.
Connaître l'heure et la gravité du changement est utile pour déterminer ce qui a pu en être la cause. Revenons à WebPageTest pour créer un environnement d'atelier afin de procéder à d'autres tests.
Mesurer les décalages de mise en page dans WebPageTest
Comme pour la mesure du CLS dans WebPageTest, vous devrez utiliser une métrique personnalisée pour mesurer les décalages de mise en page individuels. Heureusement, le processus est plus simple maintenant que Chrome 77 est stable. L'API Layout Instability est activée par défaut. Vous devriez donc pouvoir exécuter cet extrait de code JavaScript sur n'importe quel site Web dans Chrome 77 et obtenir des résultats immédiatement. Dans WebPageTest, vous pouvez utiliser le navigateur Chrome par défaut sans avoir à vous soucier des indicateurs de ligne de commande ni à utiliser Canary.
Modifions ce script pour générer une métrique personnalisée pour WebPageTest:
[LayoutShifts]
return new Promise(resolve => {
new PerformanceObserver(list => {
resolve(JSON.stringify(list.getEntries().filter(entry => !entry.hadRecentInput)));
}).observe({type: "layout-shift", buffered: true});
});
La promesse de ce script se résout en une représentation JSON du tableau plutôt qu'en un tableau lui-même. En effet, les métriques personnalisées ne peuvent produire que des types de données primitifs tels que des chaînes ou des nombres.
Le site Web que j'utiliserai pour le test est ismyhostfastyet.com, un site que j'ai créé pour comparer les performances de chargement réelles des hébergeurs Web.
Identifier les causes de l'instabilité de la mise en page
Dans les résultats, nous pouvons voir que la métrique personnalisée "LayoutShifts" a la valeur suivante:
[
{
"name": "",
"entryType": "layout-shift",
"startTime": 3087.2349999990547,
"duration": 0,
"value": 0.3422101449275362,
"hadRecentInput": false,
"lastInputTime": 0
}
]
Pour résumer, un seul décalage de mise en page de 34,2% se produit à 3 087 ms. Pour identifier le coupable, utilisons la vue pellicule de WebPageTest.
Si vous faites défiler la pellicule jusqu'à la marque de 3 secondes environ, vous verrez exactement ce qui est à l'origine du décalage de mise en page de 34 % : le tableau coloré. Le site Web extrait de manière asynchrone un fichier JSON, puis l'affiche dans un tableau. La table est initialement vide. L'attente pour la remplir lorsque les résultats sont chargés provoque le décalage.
Mais ce n'est pas tout. Lorsque la page est visuellement complète, soit environ 4,3 secondes, nous pouvons voir que le <h1>
de la page "Mon hébergement est-il déjà rapide ?" apparaît de nulle part. Cela se produit parce que le site utilise une police Web et n'a pris aucune mesure pour optimiser le rendu. La mise en page ne semble pas changer dans ce cas, mais l'expérience utilisateur est tout de même mauvaise, car il faut attendre si longtemps pour lire le titre.
Correction de l'instabilité de la mise en page
Maintenant que nous savons que le tableau généré de manière asynchrone entraîne le décalage d'un tiers de la fenêtre d'affichage, il est temps de le corriger. Nous ne connaissons pas le contenu du tableau tant que les résultats JSON ne sont pas chargés, mais nous pouvons tout de même le renseigner avec des données d'espace réservé afin que la mise en page elle-même soit relativement stable lorsque le DOM est affiché.
Voici le code permettant de générer des données d'espace réservé:
function getRandomFiller(maxLength) {
var filler = '█';
var len = Math.ceil(Math.random() * maxLength);
return new Array(len).fill(filler).join('');
}
function getRandomDistribution() {
var fast = Math.random();
var avg = (1 - fast) * Math.random();
var slow = 1 - (fast + avg);
return [fast, avg, slow];
}
// Temporary placeholder data.
window.data = [];
for (var i = 0; i < 36; i++) {
var [fast, avg, slow] = getRandomDistribution();
window.data.push({
platform: getRandomFiller(10),
client: getRandomFiller(5),
n: getRandomFiller(1),
fast,
avg,
slow
});
}
updateResultsTable(sortResults(window.data, 'fast'));
Les données d'espace réservé sont générées de manière aléatoire avant d'être triées. Elle inclut le caractère "█" répété un nombre aléatoire de fois pour créer des espaces réservés visuels pour le texte et une distribution générée de manière aléatoire des trois valeurs principales. J'ai également ajouté des styles pour désaturer toutes les couleurs du tableau afin de montrer clairement que les données ne sont pas encore entièrement chargées.
L'apparence des espaces réservés que vous utilisez n'a pas d'importance pour la stabilité de la mise en page. L'objectif des espaces réservés est de rassurer les utilisateurs sur le fait que le contenu sera disponible et que la page n'est pas défectueuse.
Voici à quoi ressemblent les espaces réservés pendant le chargement des données JSON:
La résolution du problème lié aux polices Web est beaucoup plus simple. Étant donné que le site utilise Google Fonts, il suffit de transmettre la propriété display=swap
dans la requête CSS. C'est tout. L'API Fonts ajoute le style font-display: swap
dans la déclaration de police, ce qui permet au navigateur d'afficher immédiatement le texte dans une police de remplacement. Voici le balisage correspondant avec le correctif inclus:
<link href="https://fonts.googleapis.com/css?family=Chivo:900&display=swap" rel="stylesheet">
Valider les optimisations
Après avoir à nouveau exécuté la page via WebPageTest, nous pouvons générer une comparaison avant et après pour visualiser la différence et mesurer le nouveau degré d'instabilité de la mise en page:
[
{
"name": "",
"entryType": "layout-shift",
"startTime": 3070.9349999997357,
"duration": 0,
"value": 0.000050272187989256116,
"hadRecentInput": false,
"lastInputTime": 0
}
]
Selon la métrique personnalisée, un décalage de mise en page se produit toujours à 3 071 ms (à peu près au même moment qu'auparavant), mais l'importance du décalage est beaucoup plus faible: 0,005%. Je peux m'en contenter.
Il est également clair dans la pellicule que la police <h1>
est immédiatement remplacée par une police système, ce qui permet aux utilisateurs de la lire plus rapidement.
Conclusion
Les sites Web complexes connaîtront probablement beaucoup plus de changements de mise en page que dans cet exemple, mais le processus de correction reste le même: ajoutez des métriques d'instabilité de la mise en page à WebPageTest, croisez les résultats avec la bande de chargement visuelle pour identifier les coupables, puis implémentez un correctif à l'aide de repères pour réserver l'espace à l'écran.
(Encore une chose) Mesurer l'instabilité de la mise en page ressentie par de vrais utilisateurs
Il est agréable de pouvoir exécuter WebPageTest sur une page avant et après une optimisation, et de constater une amélioration d'une métrique, mais ce qui compte vraiment, c'est que l'expérience utilisateur s'améliore. N'est-ce pas pour cela que nous essayons d'améliorer le site ?
Il serait donc idéal de commencer à mesurer l'instabilité de la mise en page des utilisateurs réels en plus de nos métriques de performances Web traditionnelles. Il s'agit d'un élément essentiel de la boucle de rétroaction d'optimisation, car les données sur le terrain nous indiquent où se trouvent les problèmes et si nos corrections ont eu un impact positif.
En plus de collecter vos propres données d'instabilité de mise en page, consultez le rapport sur l'expérience utilisateur Chrome, qui inclut des données de décalage de mise en page cumulé issues d'expériences utilisateur réelles sur des millions de sites Web. Il vous permet de connaître les performances de votre site (ou de vos concurrents) ou d'explorer l'état de l'instabilité de la mise en page sur le Web.