Open oskarrough opened 11 years ago
The simple reason is that browsers are wired for sync ops. You can set offsetWidth (write) and then ask for its value (read) and that is allowed. FastDOM lets you opt out of that and makes everything async. That is you would get the old value of offsetWidth before the new one was set. That's one example, and there are many properties that would trigger layout that you can Google for.
Async is great, and it would be lovely if this were the normal behaviour. But things would break if this were the default. FWIW Dart actually does DOM updates async, not that it solves this issue, but just so you know there are places where async DOM updates are normal and don't require libraries like FastDOM.
Would it be helpful to have an answer like this on the main readme?
I think so. Setting out why this even a thing is going to help devs less familiar with the area.
Sorry to resuscitate the issue but I have a question:
What's the difference between using requestAnimationFrame directly and using fastdom?
Using rAF might be OK for very small issues, but it doesn't ensure you won't be interleaving DOM read and writes, which is the thing we want to avoid.
How can you be sure that another part of your app hasn't scheduled conflicting work for the same frame?
FastDOM 'globally' coordinates when your read/write tasks are run, meaning that they are always run in the most performant way. All you have to know is that when your callback fires, the job is done :)
how does the performance of fastdom compare to virtualdom?
A virtual DOM library could consume a library like Fastdom to help it schedule operations at the correct time.
A virtual DOM library may also do a lot more. Think of fastdom as a lower level tool and a virtual DOM library as higher level abstraction.
All performance comparisons are relative. You'd need to try for yourself.
W. On 7 Feb 2015 03:57, "serapath" notifications@github.com wrote:
how does the performance of fastdom compare to virtualdom?
— Reply to this email directly or view it on GitHub https://github.com/wilsonpage/fastdom/issues/35#issuecomment-73302141.
It might sound silly (just naming and curiosity) but why measure
and mutate
functions instead of read
and write
?
Forget about it, I think I know why.
I think they are a little clearer in their intent. For example, you can 'read' an via .getAttribute()
without making DOM 'measurements'. With 'mutate' I also feel it's more explicit. Sounds more damaging and should be treated with care.
what I don't understand why do we need a library when browser actually queue dom operations before doing a repaint.
@allyraza because the browser won't stop you breaking that behaviour. If you mutate some styles and then request -- say -- offsetLeft
, the browser will run layout at that point. So while it's true that browsers do enqueue DOM operations, and that by default they will get applied in a batch, it's also true that you can break that behaviour with JavaScript, and that's what FastDOM is attempting to help with.
I see a lot of performance solutions suggest a double/inner raf, but fastdom isn't using that technique. Is there a reason? I presume it was tried and measured.
Interesting, can you give more detail/links?
This is a really interesting find, I've been giving it some thought. IIUC the issue is that if the DOM is manipulated outside of rAF
and then you schedule a rAF
with some other work inside, when browser will not actually paint the output of the DOM manipulation until that next frame, so essentially both tasks can end up running in the same frame.
So this issue is really about running blocking code inside rAF
handlers delaying the browser beginning animations. I think we need a concrete example to make sense of this; so let's take clicking a navigation button, loading some data and navigating:
button.addEventListener('click', () => {
fastdom.mutate(() => {
button.classList.toggle('ripple');
setTimeout(loadDataAndNavigateTo('some-page'));
});
});
I'm mutating the DOM and then, scheduling the loading and navigation at the end of the task queue so that is doesn't block the animation from starting. You could optionally use rAF
instead of setTimeout()
, but then you risk blocking other animations and render work.
This is a bit gross looking, I think I'd rather have a way to run something after the fastdom task is complete (AKA the animation has begun). Like:
button.addEventListener('click', async () => {
await fastdom.mutate(() => button.classList.toggle('ripple'));
loadDataAndNavigateTo('some-page');
});
That would require than we return a Promise
once the fastdom task has been run, and might make this kind of use-case a bit prettier. We'd have to make sure this was after the internalrAF
is fully complete.
Does that make sense? Have I understood the problem? :)
That's an interesting thought. Honestly I don't know enough low-level to give an opinion, but returning a "blocking" promise that resolves when the mutation is complete makes sense.
I was just looking particularly at https://github.com/wilsonpage/fastdom/blob/master/fastdom.js#L158
and wondered if fastdom.raf(fastdom.raf(flush.bind(null, fastdom)));
would be more performant? I think only empirical perf tests would determine that.
Is this still a commonly (and more so recommended) library in 2019? With render, layout and paint speeds essentially so fast and with RAF, just wondering if this great library is still recommended? Maybe the benefits of batch reads and writes persist no matter how fast V8 engine or device CPU are?
I hope fastdom disappears over time. I wouldn't reach for fastdom without diagnosing that you have a render per issue with your app. As with everything it depends. If jank is still a think on the mobile web, then there will likely be a place for fastdom.
If the DOM is abstracted away from you via a framework like React, you probably don't need fastdom.
Thanks. Not using any VDOM or really any frameworks @wilsonpage. Just Cordova. Long scrolling lists and unfortunately large DOM even though we have made significant strides to reduce. However we've had FastDOM in for years and I was considering taking it out in consideration of the advancements these past CPL years.
For long scroll you may want to check virtual scroll technic.
Fastdom sounds so efficient that I need to ask what the possible downsides are. Why is this not the default behaviour implemented in modern browsers?