<?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: Chirag Mittal</title>
    <description>The latest articles on DEV Community by Chirag Mittal (@chiragm999).</description>
    <link>https://dev.to/chiragm999</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%2F1046866%2F7c0208e1-103f-40c6-b6cb-6c08410c4c54.jpeg</url>
      <title>DEV Community: Chirag Mittal</title>
      <link>https://dev.to/chiragm999</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chiragm999"/>
    <language>en</language>
    <item>
      <title>Debouncing in React: Unleashing the Power of Efficient API Calls</title>
      <dc:creator>Chirag Mittal</dc:creator>
      <pubDate>Thu, 27 Jul 2023 11:53:07 +0000</pubDate>
      <link>https://dev.to/chiragm999/debouncing-in-react-unleashing-the-power-of-efficient-api-calls-56m9</link>
      <guid>https://dev.to/chiragm999/debouncing-in-react-unleashing-the-power-of-efficient-api-calls-56m9</guid>
      <description>&lt;p&gt;Hey there, fellow tech enthusiasts! Today, I want to take you on a journey through a problem I encountered while learning React - one that left me scratching my head and wondering how to improve performance and user experience.&lt;/p&gt;

&lt;p&gt;Picture this: a project aimed at fetching a list of movies from a remote server while the user types in an input box. Seemed straightforward, right? Well, not quite.&lt;/p&gt;

&lt;p&gt;As I delved deeper into the implementation, I stumbled into a pretty big issue, which lead to a flood of API requests, slower renders, and a waste of valuable resources. Though the tutorial I followed mentioned using &lt;code&gt;AbortController&lt;/code&gt;, it failed to limit the storm of requests that were made.&lt;/p&gt;

&lt;p&gt;Now, let me tell you something about myself - I am obsessed with Performance &amp;amp; Speed. Watching those numerous API requests go to waste wasn't something I could bear. I knew there had to be a better way. Three more weeks of learning React has brought me to this very moment - ready to share the wonders of debouncing with you all.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Makeshift Solution
&lt;/h2&gt;

&lt;p&gt;The project was configured in such a way that it would fire off a request to the server every time a keystroke happened.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchMovies&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="s2"&gt;`http://www.someapi.com/?apikey=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;s=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nf"&gt;fetchMovies&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;query&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;Taking a basic example, Typing &lt;code&gt;useState&lt;/code&gt; in the search box would result in 8 total API calls, one after each keystroke.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fkn4vxy7jxmiju7u6wnx5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fkn4vxy7jxmiju7u6wnx5.png" alt="API Requests without debouncing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, this might have been useful for auto-search completion, but to me, it was just a waste of resources. Why make 8 requests when I just need 1? Keeping that in mind, I got to work.&lt;/p&gt;

&lt;p&gt;With limited knowledge of React at hand and a fair share of trial and error, I was able to come up with a makeshift solution involving the use of &lt;code&gt;setTimeout&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's what the code looked like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AbortController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
            &lt;span class="c1"&gt;// We still need the AbortController, &lt;/span&gt;
            &lt;span class="c1"&gt;// will come back to it later&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;waitFetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchMovies&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="s2"&gt;`https://www.someapi.com??apikey=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;s=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
                    &lt;span class="p"&gt;,{&lt;/span&gt; &lt;span class="na"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt; &lt;span class="p"&gt;}};&lt;/span&gt;
            &lt;span class="c1"&gt;// Doing things here&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; 
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//timeout delay&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
        &lt;span class="nf"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;waitFetch&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//Clearing the timeout&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;query&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;&lt;a href="https://media.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%2Fs5eh1xuecaf8ugryg27i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fs5eh1xuecaf8ugryg27i.png" alt="API Requests after Debouncing (using setTimeout)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This did the trick for me. Rather than making a request every keystroke, it was only being made once I stopped typing(after some idle time). It was only way later I discovered that this technique is called &lt;code&gt;Debouncing&lt;/code&gt;. The proper implementation might be a bit different, but that's the crux of it.&lt;/p&gt;

&lt;p&gt;In essence, we are limiting the number of requests. If we are going to discard them anyways, might as well not make them in the first place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use Debouncing?
&lt;/h2&gt;

&lt;p&gt;Now you might be wondering, why go through this much of a headache to save some API calls? I get that, and there are 2 good reasons for that.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Saving User Data &amp;amp; Bandwidth: Less number of requests means that less amount of data will be transferred back &amp;amp; forth. This not only enhances the user experience but also frees up bandwidth for many important operations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cost-Effective Server Management: For server administrators, fewer API requests means reduced server load &amp;amp; data bills. Debouncing helps prevent unnecessary strain on the server. (P.S. You have a lesser risk of going broke if you use something like AWS!)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Debouncing isn't just limited to a single use case of fetching data. Instead, it can also be applied to various scenarios throughout web development, such as Window Resize events, Scrolling animations, Real-time filtering etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is AbortController even needed?
&lt;/h2&gt;

&lt;p&gt;Looking at the above example, you might be thinking why I still left the abort controller in there, if it never even gets called. There's a pretty interesting reason for that. You see, the debouncing function still has an edge case we need to address.&lt;/p&gt;

&lt;p&gt;Continuing the example from before, let's imagine the user starts typing again once the request has been made. A new request will be made after the &lt;code&gt;300ms&lt;/code&gt; delay. For some reason, let's assume the data from the new request ends up arriving earlier than the previous one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fy3e1i4j9kscelbamjc1d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fy3e1i4j9kscelbamjc1d.png" alt="API Requests without AbortController (data-racing) "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This data-racing situation could lead to the data from the latest request being overwritten by the previous one, resulting in outdated or incorrect information.&lt;/p&gt;

&lt;p&gt;To safeguard against this scenario, we hold onto the &lt;code&gt;AbortController&lt;/code&gt;. Even if the previous request has been triggered, we can use the &lt;code&gt;AbortController&lt;/code&gt; to terminate it, and ensure that only the most recent response is used.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fsi21mnisemev9meeuyka.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fsi21mnisemev9meeuyka.png" alt="API Requests with AbortController"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Beyond Debouncing!
&lt;/h2&gt;

&lt;p&gt;As we approach the end of this journey through the realm of debouncing, I hope you feel empowered to utilize this powerful technique in your web development endeavors.&lt;/p&gt;

&lt;p&gt;It's not just about writing code, it's about crafting exceptional experiences for your users and optimizing the performance of your projects.&lt;/p&gt;

&lt;p&gt;Do keep in mind that our journey doesn't end here. Debouncing is just the tip of the iceberg, and there's, even more, we can do to optimize our applications. For example, you can experiment with using &lt;code&gt;useMemo&lt;/code&gt; with the debounce function, to make it more efficient. Additionally, for a simpler solution, the &lt;code&gt;debounce&lt;/code&gt; function provided in &lt;code&gt;lodash&lt;/code&gt; is a fantastic option.&lt;/p&gt;

&lt;p&gt;Thank you for joining me on this adventure, and until we meet again, happy coding, fellow developers! I would love to hear your thoughts in the comments below.&lt;/p&gt;




&lt;p&gt;If you enjoyed this blog post, consider giving me a follow. I'll be covering more topics related to performance optimization in the future. Also, if you have any questions, feel free to reach out to me on &lt;a href="https://twitter.com/ChiragM_2015" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/chiragm999/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; anytime. I'm always ready to assist you.&lt;/p&gt;

&lt;p&gt;On a personal note, I'm currently seeking a remote React developer job. If you have any leads for job openings or freelance opportunities, I would be extremely grateful for your support!&lt;/p&gt;

&lt;p&gt;Let's continue pushing the boundaries of web development together and creating remarkable experiences for our users. The future holds endless possibilities, and I can't wait to explore them with you. Happy coding!&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>api</category>
    </item>
  </channel>
</rss>
