The Rate Limiter Part - 3

The Rate Limiter Part - 3

Welcome back to our ongoing exploration of rate limiter techniques! In our previous two-part series (Part1 and Part2), we delved into the world of Debouncing, uncovering its advantages and diverse use cases. Today, we're embarking on the next phase of our journey, where we'll uncover another compelling rate-limiting technique that caters to specific scenarios.

In Part 3 of our series, we're turning our attention to a rate limiter approach namely T********g, in this blog we'll explore its unique advantages, unravel its optimal use cases,

Are you ready to broaden your rate-limiting toolkit? Let's dive in and uncover the art of strategic performance optimization!

In many browsers, a progressive linear bar at the top of a webpage is employed to visually indicate the user's scrolling progress within that page. In this upcoming blog, we will delve into the process of creating this scrolling indicator.

Our exploration won't stop there. We'll also address a common challenge posed by traditional event handling when it comes to implementing such features. Furthermore, we'll unravel how this challenge can be effectively overcome by leveraging a rate limiter technique.

We begin our journey with a minimalist webpage adorned with an array of boxes. But that's not all. At the pinnacle of the page, a progress bar eagerly awaits, poised to dynamically expand in response to your scrolling actions. The screen we are going to build is attached below.

Ui Elements

  1. A header with a Progress bar at the bottom and the header is sticky which will stick at the top when the user scrolls.

  2. Several differently coloured boxes are listed one by one.

Functionalities

const progressBar = useRef()

Here we create a reference variable called progressBar using the useRef hook which is attached to the ref of the progress-bar so that we can get access to the DOM element (progress-bar)

<div ref={progressBar} className="progress-bar"></div>

Now, our next step is to create a handler ( updateProgressBar ) that adjusts the progress bar according to how the user is scrolling.

This handler is responsible for calculating and updating the progress-bar width in percentage

Let's breakdown our updateProgressBar

  1. targetDiv: This stores the reference to the main element, allowing us to determine how tall the entire component (the current page) is.

  2. documentHeight: This variable holds the calculated total height of the document based on these two values:

    1. targetDiv.scrollHeight: This provides the full scrollable height. It calculates both the visible part and the yet-to-be-scrolled content.\

    2. window.innerHeight: This gives us the screen height of the device.

Now, why do we subtract these two values, especially when we already have the total height of targetDiv?

Here's the catch: The targetDiv might have some part that's already visible in the viewport – essentially, the height of the screen. To obtain an accurate scrolling position, we need to subtract the viewport height from the total height.

  1. progressed: Armed with the calculated values, we can compute the percentage of scrolled content: window.scrollY / documentHeight.

  2. Lastly, the cherry on top: we update the width of the progress bar. This is done using the reference: progressBar.current.style.width = `${progressed}%`.

For better understanding refer the below image

Lastly, now we have to attach this handler to the scrolling event,

  1. window.addEventListener("scroll", updateProgessBar) listens when someone scrolls the webpage.

  2. When scrolling is detected, the updateProgessBar function is called.

  3. window.removeEventListener("scroll", updateProgessBar) used to unregister the listener on leaving the page.

The entire component altogether

The Output :

If you observe closely the log, you'll notice that the callback gets executed numerous times. This frequent firing of the scroll event can lead to inefficiencies, especially since we're calculating and updating things using the reference.

This scenario calls for an optimization, and that's where the concept of "Throttling" comes into play. Throttling is a rate-limiting technique that restricts the frequency of a function's execution. By employing throttling, we can regulate the pace at which the updateProgressBar function is triggered, avoiding unnecessary calculations and updates that can strain the performance.

Throttling?

A technique that limits the number of times a function can be called over a given period of time.

The implementation.

Here, we define a function called throttling that takes two parameters: func and limit.

  1. func is the function that we want to throttle. It's the function that we want to delay and execute only after a certain period of interval.

  2. limit is the time duration (in milliseconds) that represents the delay period. It indicates how frequently we want to wait before executing the func after the last call.

This throttling function will return a closure function which has access to the flag variable and will execute the func we passed, based on the flag

let's break down the mechanism of the throttling function:

  1. Initially, the flag is set to true, indicating that the function is ready to execute

  2. When the function executes, the flag is set to false, preventing immediate subsequent executions.

  3. Now, the throttling mechanism comes into play. It's designed to control the pace of function calls.

  4. During the next set time period (the throttle interval), even if the function is triggered multiple times, it won't execute immediately since the flag is false.

  5. Only when the throttle interval expires and the flag is set back to true, the function can execute again.

  6. This ensures that the function is called at a controlled rate, preventing rapid, potentially unnecessary, and performance-draining executions.

    In essence, the throttling technique introduces a delay between function executions, providing an optimal balance between responsiveness and efficiency.

The updated component

Here is the throttled function is implemented and the output for the same is attached below.

The impact of throttling is clear and noticeable. By implementing throttling, we've significantly curbed the frequency of function executions.

Previously, the function fired numerous times in rapid succession due to the frequent scroll events. However, with throttling in place, we've introduced a deliberate pause between executions. This optimized pacing not only conserves system resources but also ensures that the function's calculations and updates occur only when necessary, leading to a smoother and more efficient user experience. Throttling has undeniably proven its worth in taming the storm of excessive function calls.

Here is the codesanbox link throttling-example

Conclusion:

Our encounter with throttling serves as a testament to the power of rate limiting techniques in optimizing web interactions. By employing this technique, we've not only enhanced the user experience but also demonstrated the art of precision in managing event-driven functionalities.