Still using
polling
orwindow.resize
to detect element size changes?
Then you might have missed a native API truly built for element resizing — say hello toResizeObserver
.
What Problem Does ResizeObserver
Solve?
Before ResizeObserver
was introduced, developers had only a few imperfect ways to detect element size changes:
window.addEventListener('resize')
- Polling DOM dimensions with a timer
- Using
MutationObserver
with manual logic - Relying on third-party libraries
All these share the same core issue:
They track window or DOM structure changes, not the element’s own size changes.
// 👎 Can't detect element size changes
window.addEventListener('resize', () => {
console.log("The window changed, but did the element?");
});
ResizeObserver
, on the other hand, was designed specifically for this purpose:
const ro = new ResizeObserver(entries => {
for (let entry of entries) {
console.log('Element size changed:', entry.contentRect);
}
});
ro.observe(document.querySelector('#target'));
It’s built on the browser’s layout engine — asynchronous, performant, and focused purely on element-level resize detection.
Use Cases
🧭 Case 1: Chart Auto-Resize
Redraw charts (like ECharts or Highcharts) when their container size changes — avoiding stretched or squashed layouts.
const chart = echarts.init(document.getElementById('chart'));
const ro = new ResizeObserver(() => {
chart.resize();
});
ro.observe(document.getElementById('chart'));
Supports container resizing, layout changes, hide/show transitions, and more —
no need for window.resize
anymore!
🧩 Case 2: Responsive Layout Components
For button groups, menus, or card layouts that should adapt when their container width changes:
ro.observe(container);
ro.callback = entries => {
const width = entries[0].contentRect.width;
toggleLayout(width > 600 ? 'row' : 'column');
};
Use ResizeObserver
instead of resize + getBoundingClientRect()
— cleaner and more reactive.
🪞 Case 3: Nested iframes & Adaptive Containers
Elements inside an iframe can’t be detected by window.resize
,
but ResizeObserver
works perfectly!
- Supports nested components
- Works with Shadow DOM
- Ideal for micro-frontend or complex layout systems
ResizeObserver vs Other Methods
Feature / Need | ResizeObserver ✅ | window.resize ❌ | MutationObserver ⚠️ | setInterval ❌ |
---|---|---|---|---|
Element size change | ✅ Yes | ❌ No | ⚠️ Indirect | ❌ No |
Performance | ⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐ | ⭐ |
Precision | High | Low | Medium | Low |
Real-time updates | High | Medium | Medium | Low |
Code complexity | Low | Low | Medium | High |
🚀 Advanced Tips (Save This!)
1. Debounce to Control Frequency
const debounce = (fn, delay = 100) => {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
};
const ro = new ResizeObserver(debounce(entries => {
// your logic
}));
Perfect for high-frequency resize scenarios (dragging, dynamic layouts, etc.).
2. Observe Multiple Elements with State Management
const sizeMap = new Map();
const ro = new ResizeObserver(entries => {
for (const entry of entries) {
const old = sizeMap.get(entry.target);
const now = entry.contentRect;
if (!old || old.width !== now.width) {
sizeMap.set(entry.target, now);
handleResize(entry.target);
}
}
});
Useful for grid systems, dashboards, or reusable container pools.
3. Lifecycle-Safe Binding (Vue / React)
onMounted(() => {
ro.observe(elRef.value);
});
onBeforeUnmount(() => {
ro.unobserve(elRef.value);
});
Essential in Vue, React, or Web Components — ensures cleanup and prevents memory leaks.
Summary
In short:
ResizeObserver
= lighter, more accurate, and more efficient element resize detection.
But keep these in mind:
- Avoid reading layout synchronously in callbacks (like
offsetHeight
) to prevent reflow. - Use debounce/throttle for multiple elements or frequent resizes.
- Always unobserve elements properly to prevent leaks.
- Not supported in IE — use a polyfill if needed.
ResizeObserver makes listening to element size changes precise, efficient, and elegant.
Stop fighting withwindow.resize
— embrace the native solution built for modern web layouts.
Top comments (0)