fastdom-sequencer
A fastdom
extension that prioritises tasks and executes them in 'sequence' for the best possible render performance.
- User interactions are 'protected' from tasks that cause jank
- Animations/transitions are 'protected' from DOM measurements and mutations that cause jank
- Clean
Promise
based API
Usage
var sequencer = require('fastdom-sequencer')
or
<script src="node_modules/fastdom/fastdom.js"></script>
<script src="node_modules/fastdom-sequencer/fastdom-sequencer.js"></script>
API
sequencer#on()
Binds a high-priority interaction that defers any .animate()
or .mutate()
task that are executed elsewhere in the app. This protects any interaction related UI changes from jank.
sequencer.on(element, 'scroll', function(e) {
sequencer.mutate(...);
});
sequencer.on(element, 'click', function(e) {
return sequencer.animate(function() {
element.classList.add('grow');
return element;
});
});
sequencer.on(element, 'click', function(e) {
return sequencer
.animate(() => {
element.classList.add('grow');
return element;
})
.animate(() => {
element.classList.add('shrink');
return element;
})
});
sequencer.off(element, 'click', callback);
.animate()
or .mutate()
tasks inside the .interaction()
callbacks are run instantly and not deferred.
sequencer#animate()
Should contain any animation/transition code and return the target element.
sequencer
.animate(() => {
element.style.transform = 'translateY(100%)');
return element;
})
.then(() => {
});
- Is deferred by any incomplete
.on()
interactions - Run instantly if no
.on()
interactions are happening - Internally run inside
sequencer.mutate()
as DOM changes will be required to trigger animation
sequencer#mutate()
Should contain any code that is likely to cause document reflow/layout.
sequencer.mutate(() => {
var li = document.createElement('li');
list.appendChild(li);
});
- Is deferred by any incomplete
.interactions()
- Run instantly if no
.interactions()
are happening - Internally run inside
sequencer.mutate()
as DOM changes will be required to trigger animation
Chaining
Tasks can be chained together so that they happen sequentially.
sequencer
.measure(() => list.clientHeight)
.mutate(height => list.appendChild(item))
.animate(() => {
item.classList.add('reveal');
return item;
})
.then(() => {
console.log('all done!');
});