Optimisation - throttling for low end devices
GClass runs at full speed by default. No observer throttling and the GSAP ticker follows requestAnimationFrame. On low end devices you can trade a few frames for smoother interaction by capping the ticker and coalescing the three body observers.
import { initAnimations, gclassOpts } from 'gclass-anims'
// default: 0 throttle, default ticker (about 60fps via rAF)
initAnimations()
// capped at boot: 1 observer per frame, 30fps ticker
initAnimations(1, 30)
initAnimations({ throttlePerFrame: 1, fps: 30 })
// change on the fly without reload - e.g. low end mode button
gclassOpts(1, 30) // enable: 1 observer per frame, 30fps
gclassOpts() // reset: 0 throttle, default ticker
gclassOpts({ throttlePerFrame: 2, fps: 45 })
// read current runtime
import { getGClassConfig } from 'gclass-anims'
getGClassConfig() // { throttlePerFrame: 1, fps: 30 }Demo - what throttling does
Three observers watch document.body for .flip,.appear and .leave. Without throttling they fire immediately in the same microtask. With throttlePerFrame=1 a single hub observer queues mutations and drains them round robin: one observer type per requestAnimationFrame (flip then appear then leave). A mixed burst that touches all three types therefore spreads across three frames.
Demo - low end toggle
Copy this pattern for a low end device button. It calls gclassOpts on click and rewires observers immediately without a reload or a boot replay.
'use client'
import { gclassOpts } from 'gclass-anims'
export function LowEndToggle() {
const [on, setOn] = useState(false)
return (
<button onClick={() => {
const next = !on
setOn(next)
if (next) gclassOpts(1, 30)
else gclassOpts() // reset to 0, default ticker
}}>
{on ? 'Low-end ON (1, 30)' : 'Enable low-end: gclassOpts(1, 30)'}
</button>
)
}Tunables
throttlePerFrameObservers per rAF frame. 0 = no throttling (default, 3 observers immediate). 1 = round robin one per frame. 2 to 3 = two or three per framefpsGSAP ticker cap. 0 = default rAF (about 60fps, no cap). 30 = low end, 45 = balanced, 60 = capped 60initAnimations(throttle, fps)Set at boot. Also accepts initAnimations({throttlePerFrame, fps}). No args keeps last gclassOpts valuesgclassOpts(throttle, fps)Live switch. Both args optional, missing falls back to 0. gclassOpts() resets. Also accepts gclassOpts({throttlePerFrame, fps}). Rewires observers if runninggetGClassConfig()Read current {throttlePerFrame, fps}subscribeGClassConfig(cb)Subscribe to config changes, returns unsubscribeDefaults are intentionally minimal. Keep 0 and default ticker for marketing pages and desktops. Enable gclassOpts(1, 30) only when you detect a low end device or when a stress test with 150 to 200 simultaneous .appear inserts shows a long task over 50ms in the Performance panel. The hub never drops mutations, it only spreads them. A mixed burst with all three types still completes, it just takes up to three frames.