rafu
rafu is a lightweight JavaScript utility that provides a `requestAnimationFrame` shim and enhanced animation scheduling capabilities. It ensures that animations run smoothly and efficiently across different browser environments by offering a robust fallback for `requestAnimationFrame` where native support might be missing or prefixed. Beyond merely polyfilling, rafu includes a `throttled` utility for synchronizing function calls with the browser's repaint cycle, which is crucial for performance-sensitive tasks like scroll handling, resize events, or continuous input processing. The package is currently at version 1.2.0, with its latest update introducing explicit cancellation methods for both direct `rafu` calls and functions created with `rafu.throttled`. Its minimal footprint and focused functionality make it a straightforward choice for projects needing basic `requestAnimationFrame` management without introducing heavy dependencies.
Common errors
-
TypeError: rafu is not a function
cause Attempting to use `rafu` as a CommonJS module with `require()` when it might be designed primarily for ESM, or vice-versa, or if the import path is incorrect.fixEnsure you are using the correct import syntax for your module system: `import rafu from 'rafu';` for ESM, or `const rafu = require('rafu');` for CommonJS (if supported). Double-check the package.json `exports` field if present. -
TypeError: rafu.cancel is not a function
cause Calling `cancel` method when `rafu` might not be correctly imported as the default export, or `cancel` is not directly exposed as a property on the `rafu` function.fixVerify that `rafu` is imported as the default export: `import rafu from 'rafu';`. The `cancel` method is a property of this default export. -
TypeError: rafu.throttled is not a function
cause Attempting to access the `throttled` utility incorrectly, possibly expecting it as a named export instead of a property on the default `rafu` export.fixEnsure `rafu` is imported as the default export (`import rafu from 'rafu';`), then access the utility as `rafu.throttled(yourFunction);`. The `throttled` method is a property of the default `rafu` export.
Warnings
- gotcha Despite providing a `requestAnimationFrame` shim, `rafu` might still behave unexpectedly in extremely old or non-standard browser environments due to the inherent complexities of polyfilling low-level browser APIs.
- gotcha Forgetting to cancel scheduled animation frames or throttled functions can lead to memory leaks and unnecessary CPU cycles, especially if components are unmounted or removed from the DOM without proper cleanup.
- gotcha If another library or polyfill for `requestAnimationFrame` is loaded before `rafu`, it might overwrite or interfere with `rafu`'s shim, leading to unpredictable animation behavior or performance issues.
Install
-
npm install rafu -
yarn add rafu -
pnpm add rafu
Imports
- rafu
const rafu = require('rafu');import rafu from 'rafu';
- rafu.cancel
import { cancel } from 'rafu'; // Incorrect if 'cancel' is a method on the default exportimport rafu from 'rafu'; const handle = rafu(() => {}); rafu.cancel(handle); - rafu.throttled
import { throttled } from 'rafu'; // Incorrect if 'throttled' is a method on the default exportimport rafu from 'rafu'; const throttledScroll = rafu.throttled(() => {});
Quickstart
import rafu from 'rafu';
const box = document.createElement('div');
box.style.width = '50px';
box.style.height = '50px';
box.style.backgroundColor = 'red';
box.style.position = 'absolute';
box.style.top = '0px';
box.style.left = '0px';
document.body.appendChild(box);
let posX = 0;
let direction = 1;
function animateBox() {
posX += direction * 2;
if (posX > window.innerWidth - 50 || posX < 0) {
direction *= -1;
}
box.style.left = `${posX}px`;
rafu(animateBox); // Schedule the next frame
}
animateBox(); // Start the animation loop
// Example of throttling a scroll event
const scrollHandler = () => {
console.log('Scroll event throttled by rafu:', window.scrollY);
};
const throttledScrollHandler = rafu.throttled(scrollHandler);
window.addEventListener('scroll', throttledScrollHandler);
// To stop the animation after some time (demonstrating rafu.cancel)
setTimeout(() => {
const animationId = rafu(() => console.log('This will be cancelled'));
rafu.cancel(animationId);
console.log('Animation scheduled and then cancelled.');
window.removeEventListener('scroll', throttledScrollHandler);
console.log('Scroll handler removed.');
}, 5000);