ResizeObserver vs Window Resize : Quand utiliser chacun
Vous développez un composant graphique qui doit se redessiner lorsque son conteneur rétrécit. Vous utilisez window.addEventListener('resize', ...) et cela fonctionne plutôt bien—jusqu’à ce que le panneau se redimensionne suite à la fermeture d’une barre latérale, et rien ne se déclenche. C’est le problème central que cet article aborde.
Points clés à retenir
- L’événement
resizedewindowse déclenche uniquement lorsque la fenêtre du navigateur change de taille. Il ne sait rien des éléments DOM individuels. ResizeObserversurveille des éléments spécifiques et se déclenche chaque fois que leurs dimensions changent, quelle qu’en soit la cause.- Interroger les tailles d’éléments après un redimensionnement de la fenêtre est fragile—cela manque les changements dus aux basculements CSS, au contenu dynamique, au chargement de polices, et bien plus.
- Pour un style basé sur le conteneur sans JavaScript, les CSS container queries sont l’outil privilégié.
Ce que chaque API observe réellement
L’événement resize de window se déclenche lorsque la fenêtre du navigateur change de taille. C’est toute sa portée. Il ne sait rien des éléments DOM individuels.
ResizeObserver surveille des éléments spécifiques et se déclenche chaque fois que leurs dimensions changent—quelle que soit la cause. Un redimensionnement de la fenêtre, une insertion DOM, un basculement de classe CSS, un recalcul de flexbox parent—tous ces événements déclenchent l’observateur si la taille de l’élément change.
C’est la distinction fondamentale. Ils observent des choses différentes et sont généralement choisis pour des tâches différentes.
Quand utiliser l’événement Window Resize
L’événement resize de window est l’outil approprié lorsque votre logique dépend véritablement des dimensions de la fenêtre, et non de la taille d’un élément particulier :
- Basculer une mise en page de navigation mobile à un point de rupture de la fenêtre
- Redimensionner un canvas pleine page ou un contexte WebGL à
window.innerWidth/window.innerHeight - Ajuster l’état de mise en page globale qui dépend de l’espace d’écran disponible
window.addEventListener('resize', () => {
canvas.width = window.innerWidth
canvas.height = window.innerHeight
render()
})
Pour des réponses purement visuelles, pilotées par CSS, à la taille de la fenêtre, privilégiez les media queries plutôt que JavaScript.
Quand utiliser ResizeObserver
Les cas d’usage de ResizeObserver se concentrent sur un comportement au niveau du composant qui doit réagir à la taille réelle rendue d’un élément :
- Un graphique qui recalcule les échelles d’axes lorsque la largeur de son conteneur change
- Un éditeur de texte qui ajuste la mise en page de sa barre d’outils en fonction de l’espace disponible
- Un panneau redimensionnable ou un widget à volets divisés
- Tout widget embarqué qui ne contrôle pas son propre conteneur
const ro = new ResizeObserver((entries) => {
for (const entry of entries) {
const { inlineSize, blockSize } = entry.contentBoxSize[0]
chart.resize(inlineSize, blockSize)
}
})
ro.observe(document.querySelector('.chart-container'))
Lecture de la forme moderne de l’API
L’API ResizeObserver actuelle expose des tableaux contentBoxSize et borderBoxSize sur chaque entrée—chacun contenant inlineSize (largeur dans les modes d’écriture horizontaux) et blockSize (hauteur). L’ancienne propriété contentRect fonctionne toujours mais existe principalement pour la rétrocompatibilité. Privilégiez contentBoxSize[0] dans le nouveau code.
Discover how at OpenReplay.com.
Pourquoi ne pas simplement interroger après un Window Resize ?
Un modèle courant—écouter l’événement resize de window puis appeler getBoundingClientRect() sur les éléments—est fragile. Il manque les changements de taille qui n’ont rien à voir avec la fenêtre : chargement de contenu dynamique, basculement de classes CSS, injection d’enfants, chargement de polices. ResizeObserver capture tous ces cas. L’interrogation après un redimensionnement de fenêtre ne le fait pas.
Performance et boucles de rétroaction
Les callbacks de ResizeObserver s’exécutent après la mise en page et avant le rendu, ce qui signifie que les lectures DOM à l’intérieur du callback reflètent la mise en page actuelle sans forcer un recalcul. C’est structurellement plus sûr que de lire les propriétés de mise en page à l’intérieur d’un gestionnaire d’événement resize.
Un piège : si vous modifiez la taille d’un élément observé à l’intérieur de son propre callback, vous déclenchez une autre observation. ResizeObserver gère cela en traitant les observations à des profondeurs DOM progressivement plus importantes dans la même frame et finit par signaler une erreur si le cycle ne se résout pas—évitant ainsi les boucles infinies. Vous devez néanmoins être délibéré sur ce que vous écrivez à l’intérieur du callback.
L’avantage en termes de performance de ResizeObserver devient significatif lorsque votre callback touche la mise en page ou lorsque les changements de taille d’élément se produisent indépendamment du redimensionnement de la fenêtre.
L’alternative des CSS Container Queries
Si votre objectif est de styler un élément en fonction de la taille de son conteneur, les CSS container queries sont l’outil approprié—aucun JavaScript nécessaire. Réservez ResizeObserver aux cas où la logique d’exécution, et non le style, doit réagir aux changements de taille.
| Scénario | Meilleur outil |
|---|---|
| Changements de mise en page à l’échelle de la fenêtre | Événement resize de window |
| Les dimensions d’un élément pilotent la logique JS | ResizeObserver |
| Style basé sur le conteneur uniquement | CSS container queries |
Conclusion
Utilisez l’événement resize de window lorsque vous vous souciez de la fenêtre. Utilisez ResizeObserver lorsque vous vous souciez d’un élément. Utilisez les CSS container queries lorsque vous avez uniquement besoin de modifier les styles. Ces trois outils couvrent l’ensemble de l’espace du comportement responsive—choisissez celui qui correspond à ce que vous mesurez réellement.
FAQ
ResizeObserver se déclenche lorsque les dimensions d'un élément changent, donc réduire un élément à une largeur ou hauteur nulle le déclenchera. Cependant, il ne se déclenche pas pour les changements de visibilité ou d'opacité qui laissent les dimensions intactes. Pour une véritable détection de visibilité, utilisez plutôt IntersectionObserver.
L'observateur cesse automatiquement de suivre un élément une fois qu'il est collecté par le ramasse-miettes. Cependant, appeler explicitement unobserve ou disconnect est une bonne pratique, en particulier dans les applications monopages ou les composants de framework avec des cycles de montage et démontage, pour éviter les références obsolètes et les callbacks inattendus.
Oui. ResizeObserver bénéficie d'une large prise en charge dans Chrome, Firefox, Safari et Edge. Si vous devez prendre en charge des navigateurs plus anciens, un polyfill est disponible, bien qu'il repose en interne sur l'interrogation et les observateurs de mutations, il n'égalera donc pas les performances natives.
Généralement non pour les mises à jour d'interface légères. ResizeObserver regroupe déjà efficacement les notifications dans le pipeline de rendu. Cependant, si votre callback déclenche un travail en aval coûteux comme des requêtes réseau ou des calculs lourds, différez ce travail spécifique plutôt que l'ensemble du callback.
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.