This repository has been archived by the owner on Jul 29, 2019. It is now read-only.
Prevent items from being repeatedly redrawn while off screen #3633
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This fixes #3249 again, because my previous PR #3250 got overwritten. (Possibly by #3475) Additionally, this time I feel that this change is a bit more robust than my previous one.
The problem
When an item is outside of the currently visible range, it is hidden by Group.prototype._checkIfVisible(). This detaches the item from the DOM. The next time the group containing the item is drawn, Group.prototype._redrawItems calls RangeItem.prototype.redraw(), which in turn calls RangeItem.prototype._appendDomElement(). This function detects that the item is not attached to the DOM and re-attaches it, triggering a reflow event.
In my application I have several thousand items which are offscreen at a given time, and so this unnecessary redrawing degrades performance quite significantly.
My solution
Currently when a group is drawn, each item is shown (and redrawn) if it currently not displayed. With my change, each item is shown if it's currently not displayed AND it either should be visible, or it's never been visible before.
This correctly gets the size of elements when they are first added, doesn't update the size of the element while it's not visible but immediately updates the size once the element becomes visible again.
Performance impact
It's hard to produce a minimal example illustrating this issue because it only really becomes noticeable when you have thousands of items, each one with a non-trivial template. I hope it will be sufficient to provide some performance numbers from my own app:
Before this patch, when I panned/zoomed the timeline in my application I would dip to 7-10fps. Now, my app only dips to 16-17fps. (I'm still working on improving performance in my app)