
Throttling Scroll Events in JavaScript

When you're working on a modern website or web application, you often tend to be working with a lot of moving parts. Things might need to animate on scroll, or you might need to detect when something is visible on screen and have it fade in (although using the Intersection Observer API would be far more performant for this). There are all kinds of reasons to attach a listener to the scroll event, but it can be a good idea to 'throttle' these functions.
One of the key reasons to throttle these functions (and listeners) is to avoid performance degradation; unlike some other events, onScroll tends to trigger very frequently which leads to lower performance, especially if you process a lot of data within that event, causing the interface to slow down or feel laggy. It also forces an increase in client‑side resource use (i.e., the CPU and/or GPU), which can leave to even more lagging.
I'm sure you've arrived on websites in the past where your computer's fans whir into life as soon as things start to load. YouTube used to be extremely bad for this (although more due to general non‑performant code rather than scroll events in particular).
Another reason to throttle or regulate how often your functions run is a little less back‑end focused, but no less important. If you've got animations being triggered on scroll, you can run into a fair few weird visual glitches if you're running them without regulation. Things can look unfinished, broken, too quick, or just unpleasant if you don't slow them down long enough to seem intentional. You can avoid ‑ or at the very least mitigate ‑ these issues by preventing your functions from running, or your listeners from checking, every single millisecond. This is called 'throttling'. So, how do we throttle our scroll events?
Building a Diy Throttle Function
First things first, what do we need our throttling function to do?
To effectively throttle a function, we need to be able to check when it was previously run, then check that a certain amount of time (which we need to be able to have control over) has passed since that last run, and then run the function again if that amount of time has passed.
That all sounds relatively straightforward, so let's whip something up to handle this for us:
// Set up the throttler const throttle = (fn, delay) => { // Capture the current time let time = Date.now(); // Here's our logic return () => { if((time + delay - Date.now()) <= 0) { // Run the function we've passed to our throttler, // and reset the `time` variable (so we can check again). fn(); time = Date.now(); } } } // Here's a dummy function that we want to throttle function runOnScroll(){ console.log('function fired!'); } // We can use this like so (this will run runOnScroll at most once per second): window.addEventListener('scroll', throttle(runOnScroll, 1000)); And that's it ‑ our DIY throttling function is done and ‑ without coincidence ‑ this is similar to how the Lodash throttle function works.
But what if you want to play it safe and use a library? There may be some edge cases that our function doesn't cover, so if you want to make sure you're not missing anything, it can be really handy to grab a specifically‑made library to take care of this for you.
Using a Library
There are a couple of throttling libraries out there. I mentioned Lodash just above and ‑ personally ‑ I'd recommend it above other similar offerings. It's an excellent library when it comes to dealing with performance enhancements and is small enough not to bloat your code. Especially if you only import the parts you need, when you need them. It's open‑source, well‑vetted and tested, and easy to integrate into your projects.
Here's a brief example of how you could use the Lodash throttle function (after you've added it as a dependency or otherwise integrated it into your web app or site):
import { throttle } from 'lodash';const runOnScroll = () => { console.log('function fired!');}window.addEventListener('scroll', throttle(runOnScroll, 250));If you take a look at the throttle documentation, you'll see that all this is doing is saying: when the user is scrolling, trigger the 'runOnScroll' function at most once every 250 milliseconds.
The Wrap‑Up
Function throttling is important to avoid performance degradation, especially as designs get more and more complex, with ever more moving parts. There are plenty of ways to code a makeshift throttler yourself, but if you want something reliable and bulletproof, I would generally go with a purpose‑made library like Lodash, especially if you have a use for some of the other features the library offers too.
Related Articles

What A Levels Do You Need for Software Engineering? 
Understanding the Nullish Coalescing (??) Operator in JavaScript. Understanding the Nullish Coalescing (
??) Operator in JavaScript
What Makes a Great JavaScript Developer? What Makes a Great JavaScript Developer?

Semantic HTML. Semantic HTML

Creating Custom Viewport Units Instead of Using vh and vw. Creating Custom Viewport Units Instead of Using
vhandvwA Simple Popup Window Using jQuery. A Simple Popup Window Using jQuery

Exporting and Importing Using ES6 Modules. Exporting and Importing Using ES6 Modules

The React Context API: When to Use It and When Not to. The React Context API: When to Use It and When Not to

Controlling Element Transparency with CSS opacity. Controlling Element Transparency with CSS
opacity
The Quirks of z‑index. The Quirks of
z‑index
What Does Front‑End Development Mean? What Does Front‑End Development Mean?

The Role of Dependency Injection in Angular. The Role of Dependency Injection in Angular