Reputation: 4186
I have the following d3 logic for rendering individual objects:
svg.selectAll("path")
.data(hugePathDataset)
.enter().append("path")
.attr("class", (d) => d.properties.cls )
.attr("id", (d) => d.properties.name )
.each(... canvas render logic ...)
For performance reasons, the svg
element above is set to display: none
, the real rendering happens on canvas via d3
's projection logic. The svg element is still needed, however, for later updates to canvas (such as changing color of each path individually).
My dataset includes over 60,000 paths and above code takes around 30 seconds to run. Testing it in Chrome's profiler I noticed that 90% of this time is spent in reflow. This made no sense to me since canvas doesn't reflow and the SVG with display: none
shouldn't reflow the DOM. As I continued looking into it, I realized that the reflow is not triggered by appending elements to invisible SVG, but by setting class
and id
attributes on these elements. Sure enough, if I remove lines 4 and 5, the reflow slowdown completely disappears. Setting other attributes (i.e. data-something
) does not cause a slowdown/reflow.
The problem is that I'm then unable to manipulate these paths individually later, as described above. My questions are:
class
or id
to an element with parent set to display: none
trigger a reflow?Upvotes: 2
Views: 155
Reputation: 4186
Reading D3 documentation I realized that selection.append("path")
is equivalent to selection.append(() => document.createElement("path"))
. Since document.createElement
does not yet attach the element to the DOM, it should be safe to set properties on it without a reflow. I rewrote the above logic differently and the issue went away:
svg.selectAll("path")
.data(hugePathDataset)
.enter().append((d) => {
let element = document.createElement("path");
element.id = d.properties.name;
element.className = d.properties.cls;
return element;
})
.each(... canvas render logic ...)
I still don't understand why class/id change on invisible element causes a reflow, however, but I'm no longer blocked by this.
Upvotes: 2