Improving speed by batching dom reads and writes #394
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.
Background
My team has been using dagre-d3 for a while and we were noticing that the rendering time took forever on some of our larger graphs.
Issue and Solution
In investigating, I found it was due to constant layout reflows. For every node, it reads and writes to the dom several times, each time you go from reading DOM (mostly getting bounding box) to writing DOM, it forces the layout to redraw.
What I did was separate out the loops between reading DOM for all nodes and writing DOM for all nodes.
fiddle
I have made a fiddle here that compares the original version and my version. (toggle the comments in html portion to switch between my version and original)
It turns out in the fiddle, it only saves about 200ms (from about 800ms to 600ms) however in the environment we're using it in the app where the surrounding layout is quite complicated it went from like 30 seconds to less than a second. I had a hard time replicating that in the fiddle.
This is a screeenshot of the original code's performance analysis using chrome's dev tools. Notice all the forced reflows
This a screenshot from my fork, of a similar period:
Comments
This PR was put together somewhat hastily using an old version of dagre d3 (4.1.18) because that's what my team uses right now.
It was intended to be a fork that our team uses, but since this would help anyone, I decided to make a PR. I admittedly didn't have a lot of time to updated it to the latest version, but I did find that the code hasn't changed much between v4 and master.
Even if you don't use this PR exactly, I hope you at least consider refactoring to achieve the general concept, because this will help out in a lot of situations.
If you are interested in using this PR but need it in a better/different state, please let me know!