New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8-10x slower than React at 10k item list reversal #484
Comments
@brianmfranklin Thanks for your issue! Now we have a new test that will be used to check the speed of the riot rendering engine. We'll work on this |
I get about 450 for react on my machine and about 1600 for riot. A little less dramatic. If I cut it down 5000 items it is about 450 for riot. This seems acceptable but performance enhancements are always nice.. |
I think we can still optimize a lot the riot rendering speed and fix the memory leak re-introduced with the new releases #480 |
I agree that losing the DOM element references is less than ideal. I am glad to have contributed in some way to any improvements that come of it. I am not sure if 10k is a realistic real world case, at least not commonly, however I think it is reasonable to think someone might have a grid view with some x thousands of rows that get re-sorted when a heading is clicked. Somewhere there is a balance between the speed of the computer and the browser, the size of the list, and Riot's optimizations. For anyone who is wondering, I realized why the timing text didn't get updated until after the second button click. It's because the automatic update() that gets invoked after the clicked() handler happens before the setTimeout() sets the timeTaken property. So you are actually seeing the timeTaken on the PREVIOUS reversal, not the one that just happened. Here is an adjusted version: |
Here's native test:
I will work these results out to Riot. |
@pakastin Awesome test, I think a combination of RAF + documentFragment would be awesome |
Here's
Edit: Actually in Safari |
I think we have to use
|
I think so too |
Here's a Riot-test with There's something else wrong, because I still get delays over one second (compared to 30 ms on my native version). It's a bit faster than Here's what I did: |
|
Hmm.. it seems the problem is somewhere else.. |
I think another possible bottleneck is |
Oh, really? Hmm... |
It looks like the algorithm inside Maybe supplying unique keys could be optional? Then a more efficient algorithm is possible. |
I don’t know the internals of Riot at this point, but if appendChild is faster, then would it be possible to basically clear out the parent’s children, then rebuild the parent element out of 3 segments of children:
Or would this cause other problems, e.g. with event handlers firing on these temporary node removals?
|
Ok. One of the reasons the React example is fast is because it doesn't preserve the elements between renders. We can tell React to reuse elements. This makes it about twice as slow in my tests. See for yourself: http://jsfiddle.net/paldepind/w674Lv7p/4/ |
A 2x difference from the normal React behavior (resulting in 1 sec to reverse) would still be quite an improvement and probably quite acceptable. Notably, that 1 sec becomes around 4 seconds when doubling the list size to 20k with the keyed React demo. So there's certainly some dropoff point on the list size/performance curve, even with React. |
Definitely need to address this one. My guess is that this is caused by cascading updates, since every time a parent is updated all the children are updated as well. I'm sure this can be fixed. |
Here is quite fast way to reorder:
That all should happen during one event loop to prevent flashing to white. |
Wow. That’s quite an improvement. And only takes 33% the time that the keyed React demo does with a 20k list. Well done.
|
@pakastin, You're not only timing the actual reordering but also the idle time between the frames? I get a more accurate smaller timing by not doing that: http://jsfiddle.net/paldepind/rju8rzmn/4/ The performance is very impressive. For me it's quite a bit faster in Firefox though. |
Tnx guys!! Would you like to make a pull request? I am really excited about the results in riot |
@paldepind, |
I don't think this can be pulled. The problem is that @pakastin program rebuilts the entire list. This is faster in the current case when the entire list of elements is to be reversed. But, if only one item was moved, the current Riot implementation would only move one element but this code would still rebuilt the entire list. @pakastin, The update happens inside |
I created a test project for DOM updates and it happened to become a new framework called It's heavily inspired by Riot.js 2.0, but doesn't have all the features like templating/binding/routing: Be free to copy the ideas from |
Thanks @pakastin we will update riot using also your contribute |
After many tests I have decided to keep the current riot each method ( without DOM reordering ). |
Totally fine with that. No reason to block the development because of the lack of reordering. btw: last time I checked the child elements lacked the |
@tipiirai could you check please the |
I'd argue the reasons for slowdowns are somewhere else. Here's 10 000 items reordering: Here's documentFragment -version, again 10 000 items reordering: I'm getting ~30-40 ms rendering time (Chrome/Safari) – I don't think that's slow.. |
Thanks for your input @pakastin but I think in this post we have a bit lost the point.
Right now I consider this topic closed and I am moving forward improving other riot features. Discussing about this without any new pull request is pointless to me peace ✌️ |
That is just fantastic job @GianlucaGuarini ! |
Just a question. I need to make drag-n-drop sortable list. Is it possible with new version of each.js without dom reordering? |
@gut4 of course it will.. It all depends from your code base. You should always keep your html list in sync with your javascript data collection. |
Riot 2.2.0 is finally out! I will close this issue hoping our users will not complain the old each method 😄 |
Awesome! |
great! |
I just got mesmerized with all the hard work, this is great!. I learn a lot of stuff! |
there is clealy a regression in 2.3.x (tried 2.3.15), it requires more than 10s for the same jsfiddle. In best cases it takes 2s. Riot 2.4.0 is taking 1,5s here. Riot 2.2.4 takes less than 300ms. that is probably related to the huge slowdown I'm having to render a big list (more than 40s to render) I'll probably revert the app back to riot 2.2.0 if there is no easy fix for this? |
@GianlucaGuarini the version you posted at http://jsfiddle.net/gianlucaguarini/cbjuek58/ still take less than 100ms, is it possible to use that same code in new riot versions? |
Just use the |
With PS: Edited the original fiddle at http://jsfiddle.net/brianmfranklin/j05ukz2r/ |
Also it is important to note that the slowdown also applies to the initial rendering, which makes a really bad user experience in the page load. |
@brauliobo it's already on our todo list #1694 . This does not mean that rendering huge lists on the clientside with any framework is not insane IMHO |
nice @GianlucaGuarini. one thing to note is that the improvement proposed at http://jsfiddle.net/paldepind/rju8rzmn/4/ is taking +400ms to render, so still http://jsfiddle.net/gianlucaguarini/cbjuek58/ is much better (and also riot 2.2) |
btw, in my usecase the list has almost 6k items, the each loop is using |
sorry for buzz here, the issue I have is actually another problem, reported at #1819 |
I was very interested in seeing how fast Riot was compared to React based on the intro docs.
So I put together these simple demos to help me learn and compare.
10k item list with reverse button. After you click the button, you'll see the time it took to reverse and finish rendering. (Actually, in a separate issue, I don't understand why you have to click the button twice on the Riot version before the timing text appears.)
React: http://jsfiddle.net/brianmfranklin/w674Lv7p/
Riot2: http://jsfiddle.net/brianmfranklin/j05ukz2r/
On my MacBook Pro, I consistently get about 2500 ms for Riot, and only 250-350ms for React.
I thought maybe this was a quirk of how I was having to measure the timing. But it DOES seem to actually take longer to do the re-render.
Is this expected? Or are there more optimizations to do?
The text was updated successfully, but these errors were encountered: