Sure that last example ran at close to 60fps, according to the meter, but did it really?
I mean, as a user I experienced no performance gains, because I was focused on that lower part of the UI and I think most users would as well.
Sure that last example ran at close to 60fps, according to the meter, but did it really?
I mean, as a user I experienced no performance gains, because I was focused on that lower part of the UI and I think most users would as well.
Classic example of this is a naive markdown preview box that updates on every keypress. As the input grows, the experience becomes more intolerable until you're left typing the post in notepad and pasting it into the <textarea>.
You are only able to look past it here because of the contrived example. Though I found the demonstration intolerable and would hope, as a user of your application, that you wouldn't settle on "meh, the user won't notice/care." Especially since you don't notice it on your developer workstation and I'm stuck using it from my low powered mobile device.
Actually I would just debounce it and add a spinner. No need to shoehorn additional operations in between, which are going be outdated in a split second anyway.
So it just depends on how much you care about UX. And consider my markdown preview example where UI lock on every Nth keypress is hardly better than every keypress.
If you don't care, then why bother with auto-updating on keypress at all? Just wait for user to press enter. Much less jarring for the user than a shoddy half-solution.
No, it means it happens only after the user stopped typing for a while - a very different experience.
If you don't care, then why bother with auto-updating on keypress at all? Just wait for user to press enter.
Doesn't cover all the cases and you have to update eventually - after the first debounced event goes through is a good moment.
Internally, React manages a list of updates. Whenever you trigger one, it will be added to the list but the next re-render will only start after the previous one has finished (this is of course a simplified explanation but you get the idea).
This batching gives us the best of both worlds: We start rendering as soon as we have data and don’t have “idle” time in which the UI is unresponsive (like a long debounce function) but we still batch all updates between the different renderings so that we can skip individual updates to save time.
Because now I see mostly the cost of having pieces of the render function shoehorned between input events just so that they can be discarded, because once the render function finishes it's grossly outdated.
There is also the other problem with debounce that was pointed out earlier: The main thread _will be blocked_ when a long running tasks is executed, no matter _when_. You mentioned that the block would happen _after_ the user type in so it would be less noticeable but this is only an approximation. If you have animations on your website that use rAF, the block will still be very visible. Also if the user continues to type.
That said, I know that this is a contrived example and it might not be used as-such in a real world application. I also think it's not comparable to your auto-saving input example that would maybe be better off with using a debounce call. I'm sure that better examples for this use case will follow.
Edit: I can recommend Dan's talk at JSConf Iceland last year. He speaks about debounce as well: https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react-...
Taking a second to correlate that with results I am willing to accept, but if an app is janky with basic interactions I am leaving.
You can see the difference between first and second approaches that way. Although both would be fast if we remove that artificial slowdown (simulating a larger app).
However I also want to note that you shouldn’t base your idea of what Concurrent Mode will feel like based on an alpha version demo. It’s work in progress and we didn’t mean to imply it’s ready to be denied at face value. https://twitter.com/dan_abramov/status/1103769293479653376