<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Chhavi Kohli</title>
    <description>The latest articles on DEV Community by Chhavi Kohli (@chhavikohli).</description>
    <link>https://dev.to/chhavikohli</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3726117%2F1c643fe4-1112-420b-a11d-a48f2d5e1ab1.jpeg</url>
      <title>DEV Community: Chhavi Kohli</title>
      <link>https://dev.to/chhavikohli</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chhavikohli"/>
    <language>en</language>
    <item>
      <title>Nullish Coalescing (??) - Handle Defaults the Right Way</title>
      <dc:creator>Chhavi Kohli</dc:creator>
      <pubDate>Sat, 31 Jan 2026 17:55:20 +0000</pubDate>
      <link>https://dev.to/chhavikohli/nullish-coalescing-handle-defaults-the-right-way-3jcc</link>
      <guid>https://dev.to/chhavikohli/nullish-coalescing-handle-defaults-the-right-way-3jcc</guid>
      <description>&lt;p&gt;Before ES2020, we(developers) mostly relied on the logical OR (||) operator for default values.&lt;/p&gt;

&lt;p&gt;Let's say we want to set pageFromApi&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const currentPage = pageFromApi || 1;&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Issue
&lt;/h2&gt;

&lt;p&gt;The || operator treats all falsy values as invalid:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;0&lt;/li&gt;
&lt;li&gt;'' (empty string)&lt;/li&gt;
&lt;li&gt;false&lt;/li&gt;
&lt;li&gt;null&lt;/li&gt;
&lt;li&gt;undefined&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;EXAMPLE&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// User is on page 0 (first page)
const pageFromApi = 0;

WRONG: page 0 gets replaced
const page = pageFromApi || 1;

console.log(page); // Output:1

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Page 0 is valid, but || thinks it's falsy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nullish Coalescing (??)
&lt;/h2&gt;

&lt;p&gt;The Nullish Coalescing Operator was introduced in ES2020 to solve this exact problem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frjp86pb4k046vityr06t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frjp86pb4k046vityr06t.png" alt="Coalescing Definition" width="800" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SYNTAX&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const result = value ?? defaultValue;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;EXAMPLE&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// User is on page 0 (first page)
const pageFromApi = 0;

// CORRECT
const page = pageFromApi ?? 1;

console.log(page); // 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Other Use Cases-
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy8fbljapdexfauh5ll39.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy8fbljapdexfauh5ll39.png" alt="Coalescing examples" width="800" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It also helps in code optimization.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// OR Logic
function getUsername(user) {
  if (user.name === null || user.name === undefined) {
    return "Guest";
  } else {
    return user.name;
  }
}

// OUTPUT examples:
getUsername({ name: "Chhavi" });   // "Chhavi"
getUsername({ name: "" });         // ""
getUsername({ name: null });       // "Guest"
getUsername({});                   // "Guest"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Nullish Coalescing
function getUsername(user) {
  return user.name ?? "Guest";
}

// OUTPUT examples:
getUsername({ name: "Chhavi" });   // "Chhavi"
getUsername({ name: "" });         // ""
getUsername({ name: null });       // "Guest"
getUsername({});                   // "Guest"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;: same output but fewer lines of code.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Should You Use ???
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Nullish Coalescing(??):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;0, false, or '' are valid values.&lt;/li&gt;
&lt;li&gt;Handling API responses or optional configs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Logical OR:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;-Any falsy value should trigger a default.&lt;br&gt;
-You intentionally want aggressive fallback behavior.&lt;/p&gt;

&lt;p&gt;----------------------------************-----------------------------&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Hoisting</title>
      <dc:creator>Chhavi Kohli</dc:creator>
      <pubDate>Fri, 30 Jan 2026 10:06:27 +0000</pubDate>
      <link>https://dev.to/chhavikohli/hoisting-5me</link>
      <guid>https://dev.to/chhavikohli/hoisting-5me</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;“Why does my code sometimes work even when I use variables before declaring them?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What Is Hoisting?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqwbi3exuer0kmeruegvs.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqwbi3exuer0kmeruegvs.JPG" alt=" " width="800" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hoisting in JavaScript is a behavior where &lt;em&gt;declarations&lt;/em&gt; of variables, functions, and classes are processed and allocated memory during a compilation phase (Creation Phase) before the code is executed line by line.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This process is not a literal "moving up" of your code, but rather the JavaScript engine's way of creating an "environment record" for the current scope.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(a);
var a = 10;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Output
&lt;/h2&gt;

&lt;p&gt;According to definition from google variable is shifted to top. So output should be 10;&lt;/p&gt;

&lt;p&gt;10❌&lt;br&gt;
undefined✅&lt;/p&gt;

&lt;h2&gt;
  
  
  How?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs2ydaonh9uxn579dh9fj.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs2ydaonh9uxn579dh9fj.JPG" alt=" " width="800" height="1170"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Only declarations not initialisation &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Under the Hood&lt;/strong&gt;: The Two Phases &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Creation Phase (Compilation/Memory Allocation):&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The engine reads the entire scope of the code (global or function scope).&lt;/li&gt;
&lt;li&gt;It identifies all function and variable declarations (var, let, const, function).&lt;/li&gt;
&lt;li&gt;It allocates memory for these declarations in a memory container called the Variable Object.&lt;/li&gt;
&lt;li&gt;For var declarations, a placeholder value of undefined is assigned.&lt;/li&gt;
&lt;li&gt;For let and const declarations, they are hoisted but remain uninitialized (will discuss further in blog).&lt;/li&gt;
&lt;li&gt;For function declarations, the entire function definition is stored in memory, allowing them to be called anywhere within their scope.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv4qo8eny36p3z2a4efr1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv4qo8eny36p3z2a4efr1.jpg" alt=" " width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;TEMPORAL DEAD ZONE - Zone created for the duration between memory allocated and initialisation statement is executed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Execution Phase:&lt;/strong&gt;&lt;br&gt;
The engine begins running the code line by line.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Because memory has already been allocated, variables and functions are available for use, even if the line where they were "declared" in the source code hasn't been reached yet.&lt;/li&gt;
&lt;li&gt;When the engine encounters an assignment (=), it updates the value in the allocated memory space. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How let, const hoisting different from var.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqsz94ap7dbesoga0iaz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqsz94ap7dbesoga0iaz.png" alt=" " width="800" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>basic</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Intersection observer</title>
      <dc:creator>Chhavi Kohli</dc:creator>
      <pubDate>Sun, 25 Jan 2026 10:49:39 +0000</pubDate>
      <link>https://dev.to/chhavikohli/intersection-observer-5807</link>
      <guid>https://dev.to/chhavikohli/intersection-observer-5807</guid>
      <description>&lt;h2&gt;
  
  
  what?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;The Intersection Observer API is a modern JavaScript web API.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Observer lets you react when an element enters or leaves the viewport—efficiently and without &lt;em&gt;performance pain&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Problem it solves.&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
 Before Intersection Observer, detecting visibility usually meant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Listening to scroll events&lt;/li&gt;
&lt;li&gt;Manually calculating element positions&lt;/li&gt;
&lt;li&gt;Running that logic constantly while scrolling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hurts performance&lt;/li&gt;
&lt;li&gt;Scales poorly as pages get complex&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  why?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Much better performance&lt;/strong&gt;
Browser handles visibility checks internally
No continuous scroll listeners
Callbacks run only when visibility changes
Result: smoother scrolling and lower CPU usage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cleaner, simpler code&lt;/strong&gt;
Instead of math-heavy scroll logic, you get:
Clear declarative rules
A single observer watching multiple elements
You describe what you care about, not how to calculate it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Perfect for lazy loading&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Common use cases:&lt;/em&gt;&lt;br&gt;
Images/videos load only when near the viewport&lt;br&gt;
Infinite scrolling&lt;br&gt;
Initial page load time&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Great for UI effects&lt;/strong&gt;
Use it for:
Animations on scroll
Revealing sections
Highlighting nav items
Tracking impressions (analytics)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Works asynchronously&lt;/strong&gt;
Runs off the main scroll event loop
Won’t block rendering
This is huge for complex or animation-heavy pages.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  When not to use it
&lt;/h2&gt;

&lt;p&gt;If you need pixel-perfect scroll positions&lt;br&gt;
If you need to react to e very single scroll tick&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Intersection Observer is about state changes, not continuous tracking.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  how?
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const observer = new IntersectionObserver(cb,options);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Step 1: Define the callback function that runs when an intersection occurs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//cb
const handleIntersection (entries,observer) =&amp;gt; {
// work with entries[]
// each entry you can get
- intersectionRatio (what percent of target element is visible on screen).
- isIntersecting (Boolean)
- target
// perform action - load an image, start an animation
// optional _ to stop observing observer.unobserve(entry.target);}

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd7yrw0t4ji8dn48wjmt8.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd7yrw0t4ji8dn48wjmt8.JPG" alt=" " width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 2- Set options&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;options ={
root:null ( viewport or target ancestor),
rootMargin: ‘0px’,
threshold:0
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;rootMargin&lt;/strong&gt;: To adjust viewport Area or we can say changes the trigger area.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;rootMargin: “0px 0px 0px 0px” (top, right, bottom, left)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpt9eds2lcblp8xhq3ln9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpt9eds2lcblp8xhq3ln9.jpg" alt=" " width="800" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Threshold&lt;/strong&gt; : when certain amount of target section is visible callback is executed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F67bpecrhah7xmya4lj3g.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F67bpecrhah7xmya4lj3g.JPG" alt=" " width="800" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 3- select the target element and start observing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const targetElement = document.querySelector(…);
observer.observe(targetElement);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>api</category>
      <category>javascript</category>
      <category>performance</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Hidden Cost of Scroll Listeners</title>
      <dc:creator>Chhavi Kohli</dc:creator>
      <pubDate>Sat, 24 Jan 2026 14:27:14 +0000</pubDate>
      <link>https://dev.to/chhavikohli/the-hidden-cost-of-scroll-listeners-4270</link>
      <guid>https://dev.to/chhavikohli/the-hidden-cost-of-scroll-listeners-4270</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/chhavikohli" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3726117%2F1c643fe4-1112-420b-a11d-a48f2d5e1ab1.jpeg" alt="chhavikohli"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/chhavikohli/test-4ep8" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Is Your Scroll-Based Animation Killing Performance?&lt;/h2&gt;
      &lt;h3&gt;Chhavi Kohli ・ Jan 22&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#performance&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#discuss&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webapis&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>javascript</category>
      <category>performance</category>
      <category>discuss</category>
      <category>webapis</category>
    </item>
    <item>
      <title>Is Your Scroll-Based Animation Killing Performance?</title>
      <dc:creator>Chhavi Kohli</dc:creator>
      <pubDate>Thu, 22 Jan 2026 12:23:35 +0000</pubDate>
      <link>https://dev.to/chhavikohli/test-4ep8</link>
      <guid>https://dev.to/chhavikohli/test-4ep8</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Still attaching scroll listeners to trigger animations or load content?&lt;br&gt;
Here’s the practical, reliable way to ship smooth UIs at scale:&lt;br&gt;
&lt;a href="https://dev.to/chhavikohli/intersection-observer-5807"&gt; &lt;strong&gt;Intersection Observer&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  WHY?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Hidden Cost of Scroll Listeners&lt;/strong&gt;&lt;br&gt;
At first glance, scroll listeners seem harmless.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;You scroll → JavaScript runs → something animates.&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The problem is how often that code runs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;Scroll Events Fire A Lot&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;When a user scrolls, the browser can fire the scroll event up to 60 times per second (once every frame).&lt;br&gt;
That means your code is running:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;While the browser is drawing pixels&lt;/li&gt;
&lt;li&gt;While it’s calculating layouts&lt;/li&gt;
&lt;li&gt;While it’s handling user input&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your scroll handler is now competing with the browser’s most time‑critical work.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;Small Checks Can Trigger Big Work&lt;/strong&gt;&lt;/u&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;element.getBoundingClientRect();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But under the hood, it may force the browser to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recalculate styles&lt;/li&gt;
&lt;li&gt;Recompute layout&lt;/li&gt;
&lt;li&gt;Flush the rendering pipeline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;The Cost Grows with Every Element&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you check one element, it’s manageable.&lt;/li&gt;
&lt;li&gt;If you check 10 elements, that work runs 10 times.&lt;/li&gt;
&lt;li&gt;If you check 100 elements, the browser struggles.&lt;/li&gt;
&lt;li&gt;This is why scroll‑based logic often feels fine at first……and suddenly becomes janky as the page grows.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why Throttling Isn’t Enough:&lt;/strong&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“I’ll just throttle my scroll handler.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Throttling helps reduce CPU usage, but it doesn’t fix everything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Animations can fire late&lt;/li&gt;
&lt;li&gt;Elements appear after they’re visible&lt;/li&gt;
&lt;li&gt;Fast scrolling causes missed triggers&lt;/li&gt;
&lt;li&gt;Touch scrolling still feels laggy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;In other words: fewer explosions, same fire.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;A Quick Performance Smell Test&lt;/strong&gt;&lt;/u&gt;&lt;br&gt;
Open Chrome DevTools → Performance, record a scroll, and look for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Long “Event (scroll)” blocks&lt;/li&gt;
&lt;li&gt;Frequent Layout or Recalculate Style steps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you see them repeating during scroll, your page is doing too much work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaway&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Scroll listeners aren’t bad because they’re wrong.&lt;/li&gt;
&lt;li&gt;They’re bad because they make you do the browser’s job—over and over again.&lt;/li&gt;
&lt;li&gt;That’s exactly the problem Intersection Observer was designed to solve.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

</description>
      <category>javascript</category>
      <category>performance</category>
      <category>discuss</category>
      <category>webapis</category>
    </item>
  </channel>
</rss>
