npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

frame-throttle

v3.0.0

Published

A lightweight way to throttle events and callbacks using requestAnimationFrame

Downloads

5,706

Readme

frame-throttle

Build Status Coverage Status

A lightweight wrapper using requestAnimationFrame to throttle event callbacks.

Installation

npm install frame-throttle

Purpose

frame-throttle improves performance by only calling callbacks once per frame.

When listening to scroll and resize events (among others), the browser tends to fire off more events per second than are actually useful. For instance, if your event listener sets some element positions, then it is possible for those positions to be updated multiple times in a single rendered frame. In this case, all of the layout calculations triggered by setting the elements' positions will be wasted except for the one time that it runs immediately prior to the browser rendering the updated layout to the screen.

To avoid wasting cycles, we can use requestAnimationFrame to only run your event listener once just before the page is rendered to the screen. For browsers that do not support requestAnimationFrame, frame-throttle will fall back to setTimeout (see gotchas below.)

Use

To use frame-throttle, simply create your callback, and pass it to the throttle method — the return value is a throttled callback which you can pass to any method that would take your original callback, such as addEventListener and removeEventListener:

var throttle = require('frame-throttle').throttle;

var callback = function(e) {
    // handle a 'resize' event
}

var throttledCallback = throttle(callback);

window.addEventListener('resize', throttledCallback);
window.removeEventListener('resize', throttledCallback);

You can use throttle to throttle any function, not just event listeners. The function will be called once during the next animation frame using requestAnimationFrame if it exists. If requestAnimationFrame does not exist, then the callback will be called immediately, and setTimeout will be used to ignore further calls for 1/60th of a second.

Examples

.cancel()

Throttled functions can be canceled, which is useful for cleaning up after yourself when you are no longer listening to an event.

var throttledListener = throttle(listener);
window.addEventListener('resize', throttledListener);
submitButton.addEventListener('click', () => {
    window.removeEventListener('resize', throttledListener);
    // prevent any queued calls from executing on the next animation frame:
    throttledListener.cancel();
})

Binding

Throttled functions can be bound, and pass their context and args to your listener:

// count the number of times that listener is called for each event type
var counterObj = {
    resize: 0,
    scroll: 0,
};
var eventCounter = function (event) {
    this[event] += 1;
};
var throttledCounter = throttle(eventCounter);
window.addEventListener('resize', throttledCounter.bind(counterObj, 'resize'));
window.addEventListener('scroll', throttledCounter.bind(counterObj, 'scroll'));

Each bound and unbound instance is throttled separately. This means that in the above example, if the resize and scroll events were fired within the same animation frame, both counterObj.resize and counterObj.scroll would be incremented.

Gotchas

Fallback to setTimeout

There are some slight differences in how frame-throttle behaves, depending on whether or not window.requestAnimationFrame exists.

If requestAnimationFrame exists, then the callback will be called during the animation-frame callback section of the browser's next browsing context event loop. In this case the callback is called at the optimal time because all layout and dimensions will be the most up-to-date available before the page is rendered to the screen. The arguments passed to your callback will be the most recent arguments passed to your callback before the animation frame.

If requestAnimationFrame does not exist, then the callback will be called immediately, and will not be called again for at least 1/60th of a second. This allows you to make make adjustments before the next frame renders, but there is a small possibility that the information you calculate your changes off of will be out of date by the time the next frame renders. The arguments to your callback will be the arguments of the first call to the throttled callback, and will be reset 1/60th of a second after the first call to the throttled callback.

cancel()

cancel() cancels only the next scheduled run of the listener. If your throttled listener is called again after calling cancel(), your listener will be scheduled to run again during the next animation frame (or immediately if window.requestAnimationFrame does not exist.