Publié le 20 mars 2015, dernière mise à jour le 7 mai 2025
C'est lors de la mise en page que le navigateur détermine les informations géométriques des éléments: leur taille et leur emplacement sur la page. Chaque élément dispose d'informations de dimensionnement explicites ou implicites en fonction du CSS utilisé, du contenu de l'élément ou d'un élément parent. Ce processus est appelé "mise en page" dans Chrome (et les navigateurs dérivés tels qu'Edge) et Safari. Dans Firefox, il s'agit de Reflow, mais le processus est en fait le même.
Comme pour les calculs de style, les préoccupations immédiates concernant le coût de la mise en page sont les suivantes:
- Nombre d'éléments nécessitant une mise en page, qui est un sous-produit de la taille du DOM de la page.
- La complexité de ces mises en page
Résumé
- La mise en page a un impact direct sur la latence d'interaction
- La mise en page est généralement limitée à l'ensemble du document.
- Le nombre d'éléments DOM affecte les performances. Dans la mesure du possible, évitez de déclencher la mise en page.
- Évitez les mises en page synchrones forcées et les mises en page inefficaces. Lisez les valeurs de style, puis apportez des modifications de style.
Effets de la mise en page sur la latence d'interaction
Lorsque l'utilisateur interagit avec la page, ces interactions doivent être aussi rapides que possible. Le temps nécessaire pour qu'une interaction se termine (qui se termine lorsque le navigateur présente le frame suivant pour afficher les résultats de l'interaction) est appelé latence d'interaction. C'est un aspect des performances de la page que la métrique Interaction to Next Paint mesure.
Le temps nécessaire au navigateur pour présenter le frame suivant en réponse à une interaction utilisateur est appelé délai de présentation de l'interaction. L'objectif d'une interaction est de fournir un retour visuel pour signaler à l'utilisateur qu'un événement s'est produit. Les mises à jour visuelles peuvent nécessiter un certain travail de mise en page pour atteindre cet objectif.
Pour que l'INP de votre site Web soit aussi faible que possible, il est important d'éviter la mise en page lorsque cela est possible. S'il n'est pas possible d'éviter complètement la mise en page, il est important de limiter ce travail afin que le navigateur puisse présenter le frame suivant rapidement.
Éviter la mise en page dans la mesure du possible
Lorsque vous modifiez des styles, le navigateur vérifie si l'une des modifications nécessite un calcul de mise en page et une mise à jour de l'arborescence de rendu. Les modifications apportées aux "propriétés géométriques", telles que width
, height
, left
ou top
, nécessitent toutes une mise en page.
.box {
width: 20px;
height: 20px;
}
/**
* Changing width and height
* triggers layout.
*/
.box--expanded {
width: 200px;
height: 350px;
}
La mise en page est presque toujours limitée à l'ensemble du document. Si vous avez beaucoup d'éléments, il vous faudra beaucoup de temps pour déterminer leurs emplacements et dimensions.
Si vous ne pouvez pas éviter la mise en page, la clé est de réutiliser les outils pour les développeurs Chrome pour voir combien de temps cela prend et déterminer si la mise en page est à l'origine d'un goulot d'étranglement. Tout d'abord, ouvrez les outils de développement, accédez à l'onglet "Chronologie", appuyez sur "Enregistrer" et interagissez avec votre site. Lorsque vous arrêtez l'enregistrement, un récapitulatif des performances de votre site s'affiche:

En examinant la trace de l'exemple précédent, nous constatons que plus de 28 millisecondes sont consacrées à la mise en page pour chaque frame, ce qui est beaucoup trop élevé, étant donné que nous disposons de 16 millisecondes pour afficher un frame à l'écran dans une animation. Vous pouvez également voir que DevTools indique la taille de l'arborescence (1 618 éléments dans ce cas) et le nombre de nœuds nécessitant une mise en page (5 dans ce cas).
Gardez à l'esprit que le conseil général est d'éviter la mise en page dans la mesure du possible, mais ce n'est pas toujours possible. Si vous ne pouvez pas éviter la mise en page, sachez que son coût est lié à la taille du DOM. Bien que la relation entre les deux ne soit pas étroitement liée, les DOM plus volumineux entraînent généralement des coûts de mise en page plus élevés.
Éviter les mises en page synchrones forcées
L'envoi d'un frame à un écran se fait dans l'ordre suivant:

Le code JavaScript est d'abord exécuté, puis les calculs de style, puis la mise en page. Il est toutefois possible de forcer un navigateur à effectuer la mise en page plus tôt avec JavaScript. C'est ce qu'on appelle la mise en page synchrone forcée (ou parfois la réarrangement forcé).
La première chose à retenir est que lorsque le code JavaScript s'exécute, toutes les anciennes valeurs de mise en page du frame précédent sont connues et disponibles pour vous. Par exemple, si vous souhaitez écrire la hauteur d'un élément (appelons-le "boîte") au début du frame, vous pouvez écrire du code comme suit:
// Schedule our function to run at the start of the frame:
requestAnimationFrame(logBoxHeight);
function logBoxHeight () {
// Gets the height of the box in pixels and logs it out:
console.log(box.offsetHeight);
}
Les choses se compliquent si vous avez modifié les styles de la zone avant de demander sa hauteur:
function logBoxHeight () {
box.classList.add('super-big');
// Gets the height of the box in pixels and logs it out:
console.log(box.offsetHeight);
}
Pour répondre à la question de hauteur, le navigateur doit d'abord appliquer le changement de style (en raison de l'ajout de la classe super-big
), puis ensuite exécuter la mise en page. Il ne pourra alors renvoyer la hauteur correcte. Il s'agit d'un travail inutile et potentiellement coûteux.
Par conséquent, vous devez toujours regrouper vos lectures de style et les effectuer en premier (lorsque le navigateur peut utiliser les valeurs de mise en page du frame précédent), puis effectuer les écritures:
Une version plus efficace de la fonction précédente serait la suivante:
function logBoxHeight () {
// Gets the height of the box in pixels and logs it out:
console.log(box.offsetHeight);
box.classList.add('super-big');
}
Dans la plupart des cas, vous n'avez pas besoin d'appliquer des styles, puis de générer des requêtes de valeurs. L'utilisation des valeurs du dernier frame devrait suffire. Exécuter les calculs de style et la mise en page de manière synchrone et plus tôt que le navigateur le souhaite peut entraîner des goulots d'étranglement. Il est donc préférable de ne pas le faire.
Éviter le thrashing de la mise en page
Il existe un moyen de rendre les mises en page synchrones forcées encore pires: en en effectuant beaucoup de suite. Examinez ce code:
function resizeAllParagraphsToMatchBlockWidth () {
// Puts the browser into a read-write-read-write cycle.
for (let i = 0; i < paragraphs.length; i++) {
paragraphs[i].style.width = `${box.offsetWidth}px`;
}
}
Ce code effectue une boucle sur un groupe de paragraphes et définit la largeur de chaque paragraphe sur celle d'un élément appelé "box". Cela semble assez inoffensif, mais le problème est que chaque itération de la boucle lit une valeur de style (box.offsetWidth
), puis l'utilise immédiatement pour mettre à jour la largeur d'un paragraphe (paragraphs[i].style.width
). Lors de la prochaine itération de la boucle, le navigateur doit tenir compte du fait que les styles ont changé depuis la dernière requête de offsetWidth
(lors de l'itération précédente). Il doit donc appliquer les modifications de style et exécuter la mise en page. Cela se produit à chaque itération.
Pour résoudre ce problème, vous devez à nouveau lire, puis écrire des valeurs:
// Read.
const width = box.offsetWidth;
function resizeAllParagraphsToMatchBlockWidth () {
for (let i = 0; i < paragraphs.length; i++) {
// Now write.
paragraphs[i].style.width = `${width}px`;
}
}
Identifier les mises en page synchrones forcées et les accès mémoire aléatoires
DevTools propose une information Forced Reflow (Reflow forcé) pour vous aider à identifier rapidement les cas de mises en page synchrones forcées (également appelées "reflow forcé"):

Les mises en page synchrones forcées peuvent également être identifiées dans le champ à l'aide de l'attribution de script d'API Long Animation Frame à l'aide de la propriété forcedStyleAndLayoutDuration
.