What is framesync?
The framesync npm package is a utility for managing timing and synchronization of animations, tasks, and other frame-based operations in JavaScript. It provides a simple API to schedule tasks to run before the next repaint, ensuring smooth visual updates.
What are framesync's main functionalities?
Scheduling tasks on the next frame
This feature allows you to schedule a function to be called at the start of the next frame. This is useful for ensuring updates are synchronized with the browser's repaint, reducing jank and improving performance of animations or UI updates.
import { onFrameStart } from 'framesync';
function update() {
console.log('Updating on the next frame');
}
onFrameStart(update);
Canceling scheduled tasks
This feature provides the ability to cancel a previously scheduled task. This is useful for avoiding unnecessary updates, especially in scenarios where component states or data might change before the scheduled execution.
import { onFrameStart, cancelSync } from 'framesync';
const update = () => console.log('This will not run if canceled before the next frame');
const process = onFrameStart(update);
cancelSync.update(process);
Other packages similar to framesync
raf-schd
raf-schd provides a similar functionality to framesync by scheduling tasks with requestAnimationFrame. It differs in its API design and focus on throttling, making it more suitable for rate-limiting updates in high-frequency scenarios.
Framesync
A frame-synced render loop for use in any JavaScript environment.
Features
- Tiny: < 1.5kb minified and gzipped.
- Compatible with all browsers, Node and React Native environments.
- Discrete render steps execute all processes in parallel.
willRender
method can prevent unnecessary render
calls.- Auto-sleeps when there are no active processes.
- Controllable time dilation - speed up or slow down every Process simultaneously.
Quick start
Install
npm install framesync --save
Use
import { Process } from 'framesync';
let frame = 0;
const frameCounter = new Process({
update: () => frame++,
render: () => console.log(frame)
});
frameCounter.start();
Render loop steps
This is the default order of execution for Process
steps, once per frame:
Framesync will fire the frameStart
method of all active processes, then all the update
methods, and so on.
Each step is optional, and each method (if defined) is called with the arguments process, frameStamp, frameDuration
, in the context of the Process
itself.
If a Process' willRender
is defined and returns false
, its render methods will be skipped for that frame.
API
Process
A Process
is a collection of methods to be run once per frame, and can be started/stopped at any time.
Create
import { Process } from 'framesync';
const process = new Process(steps, isLazy);
Arguments
steps
[object]
Object of step functions, each individually optional.
isLazy
[boolean] (optional)
If true
, this Process
will only fire when non-lazy Processes are also active.
Methods
.start()
Start the process on the next available frame.
.stop()
Stop the process after the next available frame.
.once()
Fire the process once on the next available frame.
setTimeDilation()
Control global time dilation and speed up/slow down all active Processes.
import { setTimeDilation } from 'framesync';
setTimeDilation(dilation);
Arguments
dilation
[number]
setTimeDilation(0.5);
setTimeDilation(2);
setSteps()
Warning: Changing the step execution order can break dependant modules. Only use if you have full stack control.
import { setSteps } from 'framesync';
setSteps(stepOrder);
Arguments
stepOrder
[array]
Array of step definition objects. Steps will be executed in the order of the array.
A step definition must have a step
property, which is the name of the method to be executed.
Any step can be given a decideRender
property. Subsequent steps with isRender
set to true
will be skipped if its decideRender
step method returns false
.
Example
const stepOrder = [
{ step: 'start' },
{ step: 'willRender', decideRender: true },
{ step: 'preRender', isRender: true },
{ step: 'end' }
];
setSteps(stepOrder);