Implementing Animations with Throttle in JavaScript
This document explains how to improve animation performance using throttle in JavaScript and applies throttle to solve the issue of choppy scroll animations. It also compares the differences before and after applying throttle.
What is Throttle?
Throttle is a technique that limits a function to be called 'at most once' within a 'certain time interval'. In other words, even if an event occurs multiple times within a short period, the function will only be executed once within the time interval set by the throttle. For example, if a function has a throttle of 100ms, even if the event occurs 10 times in 1 second, the function will be executed a maximum of 10 times (at 100ms intervals).
Where is Throttle Used?
Throttle can be used in the following situations:
- Preventing performance degradation due to excessive event triggering: When events such as scrolling, mouse movement, and window resizing occur frequently in a short period, the event handler can be executed excessively, causing performance issues. Throttle is used to mitigate this.
- Making animations smoother: When it is necessary to express continuous changes, such as scroll animations, the animation may be choppy or stutter depending on the event frequency. Using throttle can make animations smoother.
Problem: Stuttering and Choppy Scroll Animations
An attempt was made to implement a smooth scroll animation according to the scroll wheel event, but before applying throttle, the animation was choppy.
Reason: This is because the wheel event occurs at a very high rate, causing the window.scrollBy
function to be called excessively, preventing the browser from processing all requests.
Comparison
1. Code Before Applying Throttle
useEffect(() => {
const container = scrollContainerRef.current;
if (!container) return;
const handleWheel = (event) => {
event.preventDefault();
window.scrollBy({
left: event.deltaY,
behavior: 'smooth'
});
};
container.addEventListener('wheel', handleWheel);
return () => {
container.removeEventListener('wheel', handleWheel);
};
}, []);
In this code, the handleWheel function is executed every time a wheel event occurs. This function calculates the scroll amount using the deltaY value of the event and scrolls by calling the window.scrollBy
function. The problem is that the wheel event can occur multiple times in a very short period, which causes window.scrollBy to be called excessively, resulting in a choppy animation.
2. Code After Applying Throttle
useEffect(() => {
const container = scrollContainerRef.current;
if (!container) return;
let throttleTimer;
const handleWheel = (event) => {
if (throttleTimer) return;
event.preventDefault();
throttleTimer = setTimeout(() => {
window.scrollBy({
left: event.deltaY,
behavior: 'smooth'
});
throttleTimer = null;
}, 16);
};
container.addEventListener('wheel', handleWheel);
return () => {
container.removeEventListener('wheel', handleWheel);
};
}, []);
In the throttled code, the throttleTimer
variable is used to manage function execution. The process works as follows:
- When the
handleWheel
function is called, it checks ifthrottleTimer
exists. - If
throttleTimer
exists (meaning a previously set timer is still active), the function returns immediately. This prevents new scroll requests from being processed while a scroll animation is already in progress. - If
throttleTimer
does not exist,event.preventDefault()
is called to prevent the default scroll behavior, andsetTimeout
is used to execute thewindow.scrollBy
function after 16ms. - Inside the
setTimeout
callback function,throttleTimer
is set tonull
, resetting the throttle and allowing the function to be called again after the delay.
3. Potential Improvements
-
Initial Delay of
setTimeout
setTimeout
is used to implement the throttling mechanism.setTimeout
executes the callback function after the specified delay (16ms in this case). Consequently, when the first wheel event occurs,window.scrollBy
is invoked after a 16ms delay. This initial delay can lead to a perceived lack of immediate responsiveness, potentially being interpreted as stuttering, particularly with rapid wheel movements. (Further improvements will be explored in the future...)
Top comments (0)