<?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: Maninderpal Singh</title>
    <description>The latest articles on DEV Community by Maninderpal Singh (@msc24x).</description>
    <link>https://dev.to/msc24x</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%2F700866%2F7274ee79-799e-46e1-8bc0-45cc98326c6d.png</url>
      <title>DEV Community: Maninderpal Singh</title>
      <link>https://dev.to/msc24x</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/msc24x"/>
    <language>en</language>
    <item>
      <title>Do I really need N number of Intersection Observers in my app?</title>
      <dc:creator>Maninderpal Singh</dc:creator>
      <pubDate>Thu, 06 Feb 2025 17:53:45 +0000</pubDate>
      <link>https://dev.to/msc24x/do-i-really-need-n-number-of-intersection-observers-in-my-app-1lnm</link>
      <guid>https://dev.to/msc24x/do-i-really-need-n-number-of-intersection-observers-in-my-app-1lnm</guid>
      <description>&lt;p&gt;While initializing an &lt;code&gt;IntersectionObserver&lt;/code&gt; instance in my NextJs component, it was creating a situation where there were &lt;code&gt;N&lt;/code&gt; number of instances per &lt;code&gt;N&lt;/code&gt; number of components rendered.&lt;br&gt;
Although it should not be affecting the performance too much, unless you are rendering too many components, maybe a hundred, or a thousand?&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%2Fhre6v0j84l04pfoglu8j.gif" 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%2Fhre6v0j84l04pfoglu8j.gif" alt="A GIF that says " width="400" height="226"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Found &lt;a href="https://www.bennadel.com/blog/3954-intersectionobserver-api-performance-many-vs-shared-in-angular-11-0-5.htm" rel="noopener noreferrer"&gt;this article&lt;/a&gt; that talks about the same performance issue. It explores the IntersectionObserver API's Performance.&lt;br&gt;
Although, the article deduced that the performance bottleneck was more due to Angular's change detection. But still there are "some built-in performance advantages" by using single instance, as the actual author of the API, pointed out in their comments, &lt;a href="https://www.bennadel.com/blog/3954-intersectionobserver-api-performance-many-vs-shared-in-angular-11-0-5.htm#:~:text=Thanks%20for%20the%20analysis.%20I%27m%20the%20author%20of%20the%20IntersectionObserver%20implementation%20in%20Chrome%2C%20and%20I%20can%20confirm%20that%20there%20are%20some%20built%2Din%20performance%20advantages%20to%20using%20one%20observer%20rather%20than%20many.%20In%20your%20case%2C%20though%2C%20I%20think%20you%27re%20correct%20that%20the%20angular%20overhead%20is%20dominant." rel="noopener noreferrer"&gt;here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now to tackle this problem, the solution would be fairly easy. We can create a single instance in a parent container or a different file, to observe all the child components. That way there would be no need of creating a per component thing. We might also want our callbacks to be different for any unique component. Well, we can do it. Put the logic in that parent container? Possible, but I'm not a fan of this approach. I want to build components, that are self-sufficient and also don't spin another observer. What I felt here, that was missing, is that there is a need of some kind of systematic configuration. &lt;/p&gt;

&lt;p&gt;I can start by thinking, how a flexible abstraction over the regular API can be done. It appears I want to store my instances at a single place. I probably need a map too, so that I can identify the instance. Let's name it XObservers. It would have an entry whenever an observer registers to it. Let's call it &lt;code&gt;XObserverEntry&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;XObserver&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;xObservers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;XObserverEntry&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, what would be inside &lt;code&gt;XObserverEntry&lt;/code&gt;? It's surely going to contain an IntersectionObserver object, and information about what components are subscribed to it? That could be an array of subscribers. I used a Map here again, because I needed to identify the subscribers too, for the sake of implementation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;XObserverEntry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="na"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IntersectionObserver&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="nl"&gt;subscribers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;XObserverSubscription&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another annoying abstraction I poured into it, is &lt;code&gt;XObserverSubscription&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;XObserverSubscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;XObserverCallback&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which only contains a callback function. But a 'good' callback function, &lt;code&gt;XObserverCallback&lt;/code&gt; yeah, another abstraction. Deal with it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;XObserverCallback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IntersectionObserverEntry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But look! it gives you one &lt;code&gt;IntersectionObserverEntry&lt;/code&gt;, a single object, not a dumb array of it. But which entry exactly? Well, the element that subscribed to it. The element for which an object of &lt;code&gt;XObserverSubscription&lt;/code&gt; was created in the &lt;code&gt;subscribers&lt;/code&gt; Map.&lt;/p&gt;

&lt;p&gt;Okay, that is the design part. You can read the implementation in code. Because I cleaned the code a bit, fixed some bugs, made it a bit tolerant against small in-consistencies, and the NPM package is ready to serve.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/@msc24x/xobserver" rel="noopener noreferrer"&gt;@msc24x/xobserver&lt;/a&gt; my not so wanted, revolutionary wrapper around the regular &lt;code&gt;IntersectionObserver&lt;/code&gt;. (can I get some VC money now?)&lt;/p&gt;

&lt;p&gt;It worked for me, to provide convenience? of course, yes. Performance gain? nope (I don't think it made it worse either). And in vanilla JavaScript, I don't think you might even need it, unless you want it. Thats how I think about it.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>nextjs</category>
      <category>webdev</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
