Reduce Repeated Calls with Throttling and Debouncing
Throttling and debouncing are two techniques you can use to reduce repeated and unnecessary calls to APIs and other functions. Both techniques reduce the number of calls made, although in different ways:
-
Throttling applies a rate limit to the number of calls that can occur over a period of time. For example, one call per second.
-
Debouncing causes a function to wait a certain amount of time before running again. In this way, it limits the rate at which a function is invoked.
If you are implementing custom code that makes quick, repeated calls, whether to an API or a function, you should consider using throttling or debouncing to cut down on performance issues. If you don't use throttling or debouncing, your Commerce website can run into major performance problems.
How SuiteCommerce Implements These Techniques
One of the core libraries SuiteCommerce uses is Underscore.js. SuiteCommerce uses two methods from this library – throttle()
and debounce()
— to perform throttling and debouncing. To learn more about these methods, review the Underscore.js documentation for each one:
Throttling
As a reminder, throttling doesn't stop calls from going through; it only puts a rate limit on them. As a developer, instead of passing a function directly to where it's called, you wrap it like this:
_.throttle(function, wait, [options])
where wait
is an integer of milliseconds. The following example logs a message to the console one time every second, no matter how many times it's called:
_.throttle(function log () {
console.log('Noisy logs!');
}, 1000);
You can pass in {leading: false}
and/or {trailing: false}
to prevent the first and last calls.
If you have a function that tracks mouse movements and runs code every time the mouse moves, you might want to throttle the inputs so the JavaScript only fires a limited number of times in a set period. That way, you minimize the impact on the user's device.
Debouncing
By default, the debounce function blocks the first and all following calls until they stop, then calls using the most recent request. This technique's great for API calls because you usually only want one call to go through, and you want it to have the user's most recent data.
To use debouncing, follow this syntax:
_.debounce(function, wait, [immediate])
The immediate
parameter is optional, but if you set it to true
, debounce passes the first call and blocks the rest. The immediate
parameter works well for things like Submit buttons.
Consider this example:
_.debounce(function log () {
console.log('This will only show when you stop calling me!')
}, 1000);
If you bind the code above to a method and call it repeatedly, it waits 1000 milliseconds (1 second) before logging a message to the console.
You can use debounce for type-ahead search results. When a user starts typing a keyword, requests are sent automatically after the third character. As they keep typing, more requests go out, which can lead to a lot of unnecessary calls.
For example, if the final keyword is jackets
, then jac
, jack
, jacke
, and jacket
all get requested before the user finishes typing, but you don't need results for those. So in cases like this, you want to debounce the calls by waiting until the user finishes typing (or at least waiting a short delay), then search using the final keyword they entered.