JavaScript
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Types
-
Section 3: Strings and Numbers in Depth
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Objects and Arrays
-
Section 7: Maps, Sets, and Symbols
-
Section 8: Asynchronous JavaScript
-
Section 9: Object-Oriented and Prototypes
-
Section 10: The DOM
-
Section 11: Browser APIs
-
Section 12: Modern JavaScript (ES2015-ES2025)
-
Section 13: Functional Programming Patterns
-
Section 14: Error Handling and Debugging
-
Section 15: Testing
-
Section 16: Accessibility for JavaScript Developers
-
Section 17: Internationalization and Localization
-
Section 18: Performance
-
Section 19: Node.js Fundamentals
-
Section 20: Regular Expressions
-
Section 21: Design Patterns in JavaScript
-
Section 22: Security Basics
-
Section 23: Data Structures and Algorithms in JavaScript
-
Section 24: Practical Projects
-
Section 25: More Advanced Async Patterns
-
Section 26: More Object and Class Practice
-
Section 27: Working with Dates and Internationalization
-
Section 28: Web Components
-
Section 29: More DOM and Browser Practice
-
Section 30: Build Tooling for Vanilla JavaScript
-
Section 31: More Practice Projects
-
Section 32: Interview and Algorithm Practice
-
Section 33: Error Objects (MDN Reference)
-
Section 34: TypedArrays and Binary Data
-
Section 35: Reflection and Metaprogramming (MDN Reference)
-
Section 36: More Global Functions (MDN Reference)
135: Understanding Reflow and Repaint
Imagine you're reorganizing your home office. If you decide to move your heavy oak desk from one wall to the other, you can't just move the desk. You have to shift your chair, move the lamp, rewire your cables, and maybe even move a bookshelf to make it fit. Everything in the room is affected by that one big move. That's a lot of effort.
Now, imagine you just decide to paint your walls a different shade of blue. You don't move the desk, the chair stays put, and the cables don't budge. You're just changing the surface appearance. It's much faster and less disruptive than moving the furniture.
In the browser's eyes, moving the desk is a Reflow, and painting the walls is a Repaint. Here is how that maps to your code:
- The Furniture Move (Reflow): When you change something that affects the geometry of the page—like
width,height,margin, or adding a new element to the DOM—the browser has to recalculate the position and size of that element and every other element it affects. This is computationally expensive. - The Paint Job (Repaint): When you change something that is purely visual—like
color,background-color, orvisibility: hidden—the browser doesn't need to move anything. It just re-draws the pixels on the screen. This is much "cheaper" for the CPU.
The Heavy Lifting of Layout Shifts
I've seen a lot of developers accidentally kill their app's performance by triggering constant reflows. The trick is remembering that reflows often "bubble." If you change the width of a parent <div>, the browser doesn't just update that div; it has to check if the children need to wrap, if the sidebar needs to shift, and if the footer needs to be pushed further down the page.
// This triggers a Reflow
const box = document.querySelector('.profile-card');
box.style.width = '400px';
box.style.marginLeft = '20px';
// Every element around .profile-card might now need to move.
Quick Fixes and Visual Updates
Repaints are far more forgiving. If you're building a UI that needs to feel snappy—like a button that glows when you hover over it—stick to properties that don't trigger a layout change. I usually lean heavily on opacity or color for these types of interactions.
// This triggers a Repaint (no Reflow)
const heartIcon = document.querySelector('.like-button');
heartIcon.style.color = 'red';
heartIcon.style.backgroundColor = '#ffebee';
// The layout remains identical; the browser just swaps the colors.
The Performance Trap: Layout Thrashing
Here is where things get tricky. There is a phenomenon called "Layout Thrashing." This happens when you write to the DOM and then immediately read a layout property. To give you the correct value for the "read," the browser is forced to perform a reflow right that second, even if it was planning to batch all the changes together for later.
Look at this mistake:
// BAD: Layout Thrashing for (let i = 0; i < paragraphs.length; i++) { // READ (forces reflow to get current height) const height = paragraphs[i].offsetHeight; // WRITE (invalidates layout) paragraphs[i].style.height = (height + 10) + 'px'; }In the loop above, the browser is forced to reflow the page for every single paragraph. I've seen this turn a 10ms operation into a 200ms operation on older devices. The fix? Read all your values first, then perform all your writes. Batching is your best friend here.
📋 Practical Task
Optimizing a Dynamic Dashboard Widget
You have a dashboard widget that updates the height of a content area and changes its background color based on user data. Currently, the code is causing layout thrashing and unnecessary reflows.
Your Goal: Rewrite the updateWidget function to minimize reflows. You must separate the "read" operations from the "write" operations to prevent the browser from recalculating the layout multiple times in a single loop.
<div id="widget-container">
<div class="item">Metric A</div>
<div class="item">Metric B</div>
<div class="item">Metric C</div>
</div>
<script>
function updateWidget() {
const items = document.querySelectorAll('.item');
// CURRENT INEFFICIENT CODE:
items.forEach(item => {
// This read forces a reflow because the previous iteration's write invalidated the layout
const currentHeight = item.offsetHeight;
item.style.height = (currentHeight + 20) + 'px';
item.style.backgroundColor = 'lightblue';
});
}
// Call this function to test your optimization
updateWidget();
</script>
Requirements:
1. Create an array or object to store the measured heights first.
2. Loop through the items a second time to apply the style changes.
3. Ensure the backgroundColor change remains as a repaint-only operation.
There are no comments for now.