Back

ResizeObserver vs Window Resize: Cuándo usar cada uno

ResizeObserver vs Window Resize: Cuándo usar cada uno

Estás construyendo un componente de gráfico que necesita redibujarse cuando su contenedor se reduce. Recurres a window.addEventListener('resize', ...) y funciona en su mayoría—hasta que el panel cambia de tamaño debido al colapso de una barra lateral, y nada se dispara. Ese es el problema central que aborda este artículo.

Puntos clave

  • El evento resize de window solo se dispara cuando el viewport del navegador cambia de tamaño. No sabe nada sobre elementos DOM individuales.
  • ResizeObserver observa elementos específicos y se dispara cuando sus dimensiones cambian, independientemente de la causa.
  • Sondear los tamaños de elementos después de un cambio de viewport es frágil—pierde cambios por alternancia de CSS, contenido dinámico, carga de fuentes y más.
  • Para estilos basados en contenedores sin JavaScript, las CSS container queries son la herramienta preferida.

Qué observa realmente cada API

El evento resize de window se dispara cuando el viewport del navegador cambia de tamaño. Ese es todo su alcance. No sabe nada sobre elementos DOM individuales.

ResizeObserver observa elementos específicos y se dispara cuando sus dimensiones cambian—independientemente de qué lo causó. Un cambio de viewport, una inserción en el DOM, una alternancia de clase CSS, un reflujo de flexbox padre—todos estos activan el observador si el tamaño del elemento cambia.

Esta es la distinción fundamental. Observan cosas diferentes y generalmente se eligen para trabajos diferentes.

Cuándo usar el evento Window Resize

El evento resize de window es la herramienta correcta cuando tu lógica genuinamente depende de las dimensiones del viewport, no del tamaño de ningún elemento en particular:

  • Alternar un diseño de navegación móvil en un breakpoint del viewport
  • Redimensionar un canvas de página completa o contexto WebGL a window.innerWidth / window.innerHeight
  • Ajustar el estado de diseño global que depende del espacio disponible en pantalla
window.addEventListener('resize', () => {
  canvas.width = window.innerWidth
  canvas.height = window.innerHeight
  render()
})

Para respuestas puramente visuales impulsadas por CSS al tamaño del viewport, prefiere media queries sobre JavaScript por completo.

Cuándo usar ResizeObserver

Los casos de uso de ResizeObserver se centran en comportamiento a nivel de componente que debe responder al tamaño renderizado real de un elemento:

  • Un gráfico que recalcula escalas de ejes cuando cambia el ancho de su contenedor
  • Un editor de texto que ajusta el diseño de la barra de herramientas según el espacio disponible
  • Un panel redimensionable o widget de panel dividido
  • Cualquier widget embebido que no controla su propio contenedor
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'))

Lectura de la forma moderna de la API

La API actual de ResizeObserver expone arrays contentBoxSize y borderBoxSize en cada entrada—cada uno conteniendo inlineSize (ancho en modos de escritura horizontal) y blockSize (altura). La propiedad antigua contentRect aún funciona pero existe principalmente para compatibilidad hacia atrás. Prefiere contentBoxSize[0] en código nuevo.

¿Por qué no simplemente sondear después de un Window Resize?

Un patrón común—escuchar el evento resize de window y luego llamar a getBoundingClientRect() en elementos—es frágil. Pierde cambios de tamaño que no tienen nada que ver con el viewport: carga de contenido dinámico, clases CSS alternadas, hijos inyectados, carga de fuentes. ResizeObserver captura todos estos. Sondear después de un cambio de viewport no lo hace.

Rendimiento y bucles de retroalimentación

Los callbacks de ResizeObserver se ejecutan después del layout y antes del paint, lo que significa que las lecturas del DOM dentro del callback reflejan el layout actual sin forzar un reflow. Esto es estructuralmente más seguro que leer propiedades de layout dentro de un manejador de evento resize.

Un detalle importante: si modificas el tamaño de un elemento observado dentro de su propio callback, desencadenas otra observación. ResizeObserver maneja esto procesando observaciones a profundidades DOM progresivamente más profundas dentro del mismo frame y eventualmente reportando un error si el ciclo no se resuelve—previniendo bucles infinitos. Aún así debes ser deliberado sobre lo que escribes dentro del callback.

La ventaja de rendimiento de ResizeObserver se vuelve significativa cuando tu callback toca el layout o cuando los cambios de tamaño del elemento ocurren independientemente del redimensionamiento del viewport.

La alternativa de CSS Container Queries

Si tu objetivo es estilizar un elemento basándote en el tamaño de su contenedor, las CSS container queries son la herramienta correcta—no se necesita JavaScript. Reserva ResizeObserver para casos donde la lógica en tiempo de ejecución, no el estilo, debe responder a cambios de tamaño.

EscenarioMejor herramienta
Cambios de diseño a nivel de viewportEvento resize de window
Dimensiones de elemento impulsan lógica JSResizeObserver
Solo estilos basados en contenedorCSS container queries

Conclusión

Usa el evento resize de window cuando te importe el viewport. Usa ResizeObserver cuando te importe un elemento. Usa CSS container queries cuando solo necesites cambiar estilos. Estas tres herramientas cubren el espacio completo de comportamiento responsivo—elige la que coincida con lo que realmente estás midiendo.

Preguntas frecuentes

ResizeObserver se dispara cuando las dimensiones de un elemento cambian, por lo que colapsar un elemento a ancho o alto cero lo activará. Sin embargo, no se dispara para cambios de visibility u opacity que dejan las dimensiones intactas. Para detección de visibilidad verdadera, usa IntersectionObserver en su lugar.

El observador automáticamente deja de rastrear un elemento una vez que es recolectado por el garbage collector. Sin embargo, llamar explícitamente a unobserve o disconnect es una buena práctica, especialmente en aplicaciones de página única o componentes de framework con ciclos de vida de montaje y desmontaje, para evitar referencias obsoletas y callbacks inesperados.

Sí. ResizeObserver tiene amplio soporte en Chrome, Firefox, Safari y Edge. Si necesitas soportar navegadores más antiguos, hay un polyfill disponible, aunque se basa internamente en polling y mutation observers, por lo que no igualará el rendimiento nativo.

Generalmente no para actualizaciones ligeras de UI. ResizeObserver ya agrupa notificaciones eficientemente dentro del pipeline de renderizado. Sin embargo, si tu callback desencadena trabajo costoso posterior como peticiones de red o computación pesada, aplica debounce a ese trabajo específico en lugar de todo el 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.

OpenReplay