react-spring's fork of rafz one frameloop to rule them all
npm install @react-spring/rafzCoordinate requestAnimationFrame calls across your app and/or libraries.
- < 700 bytes min+gzip
- Timeout support
- Batching support (eg: ReactDOM.unstable_batchedUpdates)
- Uncaught errors are isolated
- Runs continuously (to reduce frame skips)
``ts
import { raf } from '@react-spring/rafz'
// Schedule an update
raf(dt => {})
// Start an update loop
raf(dt => true)
// Cancel an update
raf.cancel(fn)
// Schedule a mutation
raf.write(() => {})
// Before any updates
raf.onStart(() => {})
// Before any mutations
raf.onFrame(() => {})
// After any mutations
raf.onFinish(() => {})
// Set a timeout that runs on nearest frame
raf.setTimeout(() => {}, 1000)
// Use a polyfill
raf.use(require('@essentials/raf').raf)
// Get the current time
raf.now() // => number
// Set how you want to control raf firing
raf.frameLoop = 'demand' | 'always'
`
- Functions can only be scheduled once per queue per frame.
- Thus, trying to schedule a function twice is a no-op.
- The update phase is for updating JS state (eg: advancing an animation).write
- The phase is for updating native state (eg: mutating the DOM).write
- [Reading] is allowed any time before the phase.onFrame
- Writing is allowed any time after the phase.true
- Timeout handlers run first on each frame.
- Any handler (except timeouts) can return to run again next frame.raf.cancel
- The function only works with raf handlers.raf.sync
- Use to disable scheduling in its callback.raf.batchedUpdates
- Override to avoid excessive re-rendering in React.
[reading]: https://gist.github.com/paulirish/5d52fb081b3570c81e3a
Wrap a function to limit its execution to once per frame. If called more than once
in a single frame, the last arguments are used.
`ts
let log = raf.throttle(console.log)
log(1)
log(2) // nothing logged yet
raf.onStart(() => {
// "2" is logged by now
})
// Cancel a pending call.
log.cancel()
// Access the wrapped function.
log.handler
``