I have hundreds of list items to be animated at the same time on list updates. The easiest way to implement it, would be to use a function I have already ready:
export function moveElement(el: HTMLElement, options: {
toLeft?: string | undefined;
toTop?: string | undefined;
durationMs?: number | undefined;
fromLeft?: string | undefined;
fromTop?: string | undefined;
signal?: AbortSignal | undefined;
runInAnimationFrame?: boolean | undefined;
}): Promise<void> {
if (runInAnimationFrame) {
return runInAnimationFrame(() => {
moveElementIntern(el, options);
})
} else {
return moveElementIntern(el, options);
}
}
moveElementIntern() uses runInAnimationFrame eventually several times depending on the options:
export function runInAnimationFrame(cb: (ms: number) => void, signal?: AbortSignal): Promise<void> {
return new Promise<void>((res, rej) => {
function wrappedCb(ms: number) {
try {
cb(ms);
res();
} catch (reason) {
rej(reason);
} finally {
signal?.removeEventListener('abort', onAbort);
}
}
const id = requestAnimationFrame(wrappedCb);
function onAbort() {
assert(signal?.aborted);
cancelAnimationFrame(id);
signal.removeEventListener('abort', onAbort);
rej(signal.reason);
}
signal?.addEventListener('abort', onAbort);
})
}
Now, as I imagine for example 500 calls to moveElement parallelly, I think about if it would be more efficient to replace the hundreds of calls to moveElement which produce each for example 2 calls to requestAnimationFrame by a only one call to a new function
function moveElements(tasks: {el: HTMLElement, options: { ... }}[]) { ... }
This would mean that requestAnimationFrame is only called about 2 times instead of about 1000 times. But there would be much more logic needed in moveElements to group the actions for all elements.
So, the decision depends mainly on the effeciency of the implementation of requestAnimationFrame in the main browsers. To be honest, I only care about Firefox, Chrome, Safari, and its mobile variants.
Has anybody enough experience to answer the question without needing to implement the new version and testing it on the different browsers? Would be very appreciated! 🙂




