Improve v-for performance in SFC
What problem does this feature solve?
I've had a few problems rendering large v-for lists and was going through the SolidJS tutorial when I came across this section about nested reactivity. When trying a similar example in Vue the performance wasn't as good for small reactive updates. I read an article describing how the rendering process works in SolidJS and from what I can gather Vue does something similar. So I looked into ways that I could get better performance out of v-for loops. I found out by creating a new component I could skip v-for's diffing. Each item in the v-for becomes it's own render function and all updates inside it don't bubble to the v-for. Here are some examples:
Optimised check list - component
What does the proposed API look like?
It would be good if the sfc-compiler made this optimisation by default. Creating render functions for each v-for item so that changes to an item don't cause the whole v-for to diff.
These are some quick shots of the performance reports for the click listeners:
Unoptimised check list
Optimised check list - component
I have something planned that may address this problem. Automating v-for blocks into components has a different set of trade-offs (e.g. what if the list is largely static and should be optimized for initial render speed?) so it's more complicated than that.
@yyx990803 That's great news!
It looks like Jason Miller has got a few tricks up his sleeve for improving the performance in Preact: https://twitter.com/_developit/status/1412451442946981890?s=20
Could Vue also benefit from any of the concepts Jason is referring to (linked lists, stack machine etc) or does Vue already do something similar?
@andrewcourtice maybe! But realisticly, something like that typically involves major rewrites (like Jason is doing) so it's unlikely to happen in the short term. We may experiment with it in the future for sure.
@robertmoura We introduced v-memo
in 3.2, which can be used to optimize list rendering performance. Have you given this a try? Does that help with your use case?