The Secret Life of JavaScript: The Resize

 

The Secret Life of JavaScript: The Resize

Building self-aware components with ResizeObserver

#JavaScript #WebDev #FrontEnd #SoftwareDevelopment




The Broken Layout

Timothy clicked the "Toggle Menu" button on his new analytics dashboard. A sleek, dark-themed sidebar slid smoothly into view, compressing the main content area. But in the center of the screen, his beautiful, custom-built <canvas> chart didn't adapt. It stubbornly maintained its original width, bleeding awkwardly over the edge of its container and disappearing behind the sidebar.

He hit refresh. The chart rendered perfectly again. He grabbed the edge of his browser window and dragged it narrower. The chart resized flawlessly.

"I don't get it," Timothy sighed, dragging the window back and forth. "The window.addEventListener('resize') logic works perfectly. But when I open the sidebar, the chart just sits there and gets cut off."

The Blunt Instrument

Margaret pulled up a chair next to him, taking a sip of her dark roast. She watched him click the toggle button again, watching the canvas fail to react.

"You are relying on a blunt instrument to do precision work," Margaret said. She pointed to his event listener.

window.addEventListener('resize', () => {
  const containerWidth = chartContainer.clientWidth;
  canvas.width = containerWidth;
  drawChart(); 
});

"In the early days of the web, the only time an element changed size was when the user physically dragged the edge of their browser," Margaret explained. "But we live in the era of CSS Grid, Flexbox, and dynamic single-page applications. Elements change their geometry all the time without the viewport ever shifting a single pixel. Opening a sidebar, expanding an accordion, or injecting a new DOM node can completely alter your chart's container. The window object has no idea any of that happened."

Timothy frowned. "So how do I know when the container changes size? I can't tie the chart's redraw logic to every single button in the application that might trigger a layout shift."

"Exactly. That would be a tightly coupled nightmare," Margaret agreed. "Using window.resize to watch a specific component is like waiting for a city-wide blackout siren just to find out your toaster finished. You need a localized sensor."

The Localized Sensor

She picked up a dry-erase marker and drew a small, targeted box on the whiteboard.

"Yesterday, we used the IntersectionObserver to hand spatial mathematics over to the browser's internal C++ engine. Today, we are going to use its sibling: the ResizeObserver," Margaret said. "Instead of waiting for the city-wide blackout siren, you are going to install a smoke detector directly in the kitchen. We tell the browser engine to stand guard over one specific DOM element and tap our JavaScript on the shoulder the millisecond its dimensions change."

Timothy cleared out the window event listener and instantiated the new observer, pointing it directly at the chart's wrapper div.

const chartContainer = document.querySelector('.chart-wrapper');

// 1. Create the localized sensor
const resizeObserver = new ResizeObserver((entries) => {
  // 2. Loop through the observed elements (we only have one)
  for (let entry of entries) {
    // 3. Grab the exact new pixel dimensions provided by the C++ engine
    const { width, height } = entry.contentRect;
    
    // 4. Account for high-DPI screens for crisp canvas rendering
    const ratio = window.devicePixelRatio || 1;
    canvas.width = width * ratio;
    canvas.height = height * ratio;
    
    // 5. Redraw the canvas (debounce this call if the rendering is heavy)
    drawChart();
  }
});

// 6. Instruct the browser to watch this specific container
resizeObserver.observe(chartContainer);

// Note: Always call resizeObserver.disconnect() when the component unmounts

Self-Aware Components

"Look at the isolation of that logic," Margaret said. "Your chart component is now completely self-aware. It doesn't care if the window resizes, if a sidebar opens, or if a CSS animation shrinks its container. The browser's highly optimized internals handle the geometry tracking, and your chart simply adapts to its environment."

"And just like the Intersection Observer," she added, "modern frameworks like React have libraries like useResizeObserver that wrap this API, giving you this exact performance pattern with almost zero boilerplate. Just remember to always call disconnect() when your component unmounts to prevent memory leaks."

Timothy saved the file. He didn't touch the browser window. Instead, he clicked the "Toggle Menu" button.

The sidebar slid into view. In perfect synchronization, the browser's engine detected the layout shift, fired the observer, and the <canvas> instantly redrew itself to fit its new, narrower home. Instead of waiting for a city-wide blackout siren, the chart knew exactly when its own world changed. It was completely decoupled, highly performant, and perfectly responsive.


Aaron Rose is a software engineer and technology writer at tech-reader.blog. For explainer videos and podcasts, check out Tech-Reader YouTube channel.

Comments

Popular posts from this blog

Insight: The Great Minimal OS Showdown—DietPi vs Raspberry Pi OS Lite

The New ChatGPT Reason Feature: What It Is and Why You Should Use It

Raspberry Pi Connect vs. RealVNC: A Comprehensive Comparison