Capturing an element takes anywhere from a few milliseconds to a few hundred, depending on its size, fonts and images. Preparation does that work ahead of time so remove() can start drawing at once.
Background preparation is enabled by default with the visible-idle strategy. The library does not know which elements you will later pass to remove() and does not scan the DOM. Register every element that should be captured ahead of time with register(). Without registration, remove() still works, but capture starts only when the operation begins. Set preparation: false to disable background preparation completely.
Register elements
const effects = new Disintegrator({ preset: 'dust' });
const cards = document.querySelectorAll<HTMLElement>('[data-effects]');
effects.register(cards);
The effects.register(cards) call registers those elements for background preparation. Their snapshots are then created once they come near the viewport and the browser has a free moment.
Stop preparing elements
To stop observation before calling destroy(), save the function returned by register():
const stopPreparing = effects.register(cards);
This is an alternative to the previous registration call; do not call register() twice for the same elements. Call the saved function when background preparation is no longer needed:
stopPreparing();
It stops watching the elements and does not touch the DOM.
Registrations are reference-counted. If two components register the same element, each receives its own release function and observation stops only after both have released it.
Configure when work is allowed
const effects = new Disintegrator({
preset: 'dust',
preparation: {
strategy: 'visible-idle',
rootMargin: '300px 0px',
concurrency: 1,
shouldPrepare: (element) => element.matches('[data-effects]'),
invalidateOnResize: true,
observeMutations: false,
cachePixelBudget: 8_000_000,
},
});
| Strategy | Behavior |
|---|---|
immediate | Capture as soon as there is a free slot. |
idle | Wait for an idle moment, with a timeout so it never waits forever. |
visible-idle | Wait until the element is near the viewport, then wait for idle. |
shouldPrepare(element) runs before anything is scheduled. It filters by any condition the application knows about: element type, current state, a feature flag, a slow connection.
Control the cache directly
await effects.prepare(elements); // capture now
effects.invalidate(elements); // remove stale entries and requeue registered nodes
effects.clearPrepared(); // release every prepared snapshot
Once capture has finished, cancelling an animation can return its snapshot to the same bounded cache. Retained removals keep their source, and restorations keep it for registered elements. Changes to effect settings alone do not require another capture; invalidation, size checks, eviction and destruction still apply.
An operation never animates from a snapshot it is unsure about. If one is missing, still being taken, out of date, or was dropped from the cache, it captures a fresh one first.
Cache budget
The cache holds 8 million physical pixels by default and drops the least recently used snapshot when it goes over. Only snapshots count against it โ retained DOM elements do not. Dropping one resizes its canvas to zero so the browser can reclaim the memory behind it.
Lower the budget on memory-tight devices. Raise it only after measuring what capture actually costs you.
Invalidation
invalidateOnResize defaults to true, while observeMutations defaults to false because watching an entire DOM subtree can be expensive. Call invalidate() after a change that alters how a registered element looks.
With observeMutations: true, added nodes, text edits, non-style attribute changes, and descendant load events invalidate and requeue preparation. Inline style writes only drop the stale snapshot: animation libraries often update them every frame, so automatic recapture would create a loop. The next operation captures the current state on demand. After a one-time style update, call invalidate() if you want to prepare that state again in the background.
invalidate() invalidates both prepared canvases and the capture engine through context.invalidate. prepare() explicitly refreshes the engine too; after clearPrepared(), the next capture must refresh. This also covers CSSOM edits, which DOM mutation observers cannot detect. Custom adapters with their own caches must honor context.invalidate.