I have a question regarding scroll: On android there is something called recyclerview Create dynamic lists with RecyclerView | Android Developers It reuses components instead of adding more and more during a scroll. It seems like discourse does not do this? why is that? is there a different strategy used? I got the vague notion that the custom vdom widget system was created to address this issue (of an ever growing list of DOM elements) But to be honest I still dont get how that solves the issue. Maybe someone can shed some light on that
We only load 20 posts at a time, using what is called “virtual scrolling”.
what happens to the old dom elements? If I keep scrolling I imagine more and more elements get added to the dom tree. Do they get removed at some point?
No we leave them around, we have a “cloaking” piece of logic that replaces elements with a placeholder once you are very far from the viewport, then when you get closer to the element we uncloak by re-rendering. The threshold for this magic is quite high.
@sam Is there an article you can link me to that compares this technique with recycling components? I would be interested in reading more about it. How did you go about making this decision? I imagine A tour of how the Widget (Virtual DOM) code in Discourse works is also related to this.
I don’t think we have an article but I may be wrong. Perhaps @eviltrout remembers if we documented some of our decisions around post cloaking. Not sure.
It’s been a very long time so I don’t recall, unfortunately.
I don’t think we ever fully analyzed recycling components. Cloaking was a big win and solved our problems at the time.
@eviltrout I saw this post We finally did something about Android Performance | Evil Trout’s Blog
After years of waiting for a breakthrough in Android or Ember performance, we decided it was time to to take the nuclear option: we replaced the Ember rendering engine for our most common view with a custom virtual DOM based renderer.
So it seems like the vdom/widget system in discourse was built as a response to the android performance issues.
This commit that introduces cloaking seems to happen after the vdom/widget system:
Is cloaking and the vdom/widget system in some way related? It seems like they both address performance. Recycling components would reduce the amount of dom elements significantly, so something like the vdom/widget system wouldn’t be necessary, right?
We had cloaking before the vdom, but it was re-implemented after we noticed we needed it there too.
Recycling components should reduce memory and improve things on large topics, but it won’t speed up rendering time which widgets do considerably.
It can’t be understated that all performance issues are about tradeoffs . I think Ember does the right thing here and focuses on apps that are organized and scale up as you add more features. For the vast majority of views in your application, the framework overhead will not concern you. However, if you are rendering many nested components with many bindings, the situation can become pathological.
While Discourse might look simple on the surface, each post is rendered with quite a few components. We have many dynamic buttons, links and effects applied every time a post is rendered with over 150 attributes involved.
I saw this in the blogpost that @eviltrout wrote. It seems like Ember performance is no problem in general, but just in the specific case of discourse topics, right? Discourse topics are a very long list of components(posts) that have lots of components inside them (reply button, like button etc). This is what leads to render performance degradation.
vdom/widgets alleviate this issue somewhat, because it makes the render process less expensive. But at some point the amount of DOM elements becomes so large, that they need to be reduced by cloaking them.
Recycling components means avoiding this problem all together, by only having a fixed number of DOM elements on the screen, that get repurposed as the user scrolls across the content.
Please correct me if I mischaracterized anything.
Thanks,
Spirobel