fix: improve card open performance on boards with many cards#8112
Conversation
Signed-off-by: Dimitris Kazakos <nemphys@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
205e059 to
e80e189
Compare
grnd-alt
left a comment
There was a problem hiding this comment.
hey, thanks for your contribution!
Together with #8140 I think it could be possible to revert the transition-group change to keep the animations, but that's something to consider after the other pr is merged, so let's get this one in for now 🔥
|
Hello there, We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process. Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6 Thank you for contributing to Nextcloud and we hope to hear from you soon! (If you believe you should not receive this message, you can add yourself to the blocklist.) |
Summary
Fixes severe UI lag when opening a card on boards with a large number of cards (e.g. 200+). Clicking a card to open its details could block the main thread for several seconds due to forced layout recalculations.
Problem
On boards with many cards, opening a card's sidebar was unbearably slow. Chrome DevTools showed multi-second main-thread blocks dominated by Recalculate Style, triggered from Vue's
<transition-group>update logic (hasMove→getTransitionInfo).Two issues compounded:
<transition-group>on card labels — EachCardItemwrapped its label list in a<transition-group>. On any component update, Vue checks whether children have moved by reading layout from the DOM. With hundreds of cards (each potentially having multiple labels), this caused thousands of forced reflows on every interaction that updated the card list.$routein a computed property —currentCarddepended on$route.params.cardId, so every card component re-rendered whenever the route changed (e.g. opening or closing the card sidebar), not just the previously selected and newly selected card.Solution
<transition-group>with a plain<ul>. Label add/remove zoom animations are dropped, which is an acceptable trade-off for large boards.isCurrentCarddata, updated via a route watcher that only mutates state when this card's selection actually changes. Only the two affected cards re-render for the highlight border.Checklist
Recalculate Styleblock fromhasMoveshould be gone