Recalculate the style: why stutter so?

Let's say we have code that introduces a number of similar elements into the DOM. Something like that:

var COUNT = 10000, elements = Object.keys(Array(COUNT).join('|').split('|')); var d = document, root = d.getElementById('root'); function inject() { var count = COUNT, ul = d.createElement('ul'), liTmpl = d.createElement('li'), liEl = null; console.time('Processing elements'); while (count--) { liEl = liTmpl.cloneNode(false); liEl.textContent = elements[count]; ul.appendChild(liEl); } console.timeEnd('Processing elements'); console.time('Appending into DOM'); root.appendChild(ul); console.timeEnd('Appending into DOM'); }; d.getElementById('inject').addEventListener('click', inject); 

Demo

When this fragment runs in Firefox (25.0), the time between the call to 'inject' and the actual viewing of its results more or less corresponds to the fact that time/timeEnd . For 1000 elements, about 4 ms; for 10,000, about 40 and so on. That’s fine, right?

This is very different, however, with Chrome (30.0 and Canary 32.0 tested). Although the time to process and add is actually shorter than that of Firefox, rendering these items takes more LOT.

Surprised, I checked the Chrome profiler for different scenarios - and it turned out that the "Recalculate Style" action was a bottleneck. It takes 2-3 seconds for 10,000 nodes, 8 seconds for 20,000 nodes, and as much as 17 seconds for 30,000 nodes.


Now the real question is: has anyone been in the same situation, are there any workarounds?

One of the possible ways that we were thinking about is to limit the visibility of these nodes in the form of lazy loading ("sort of" because it is more about a "lazy display": the elements will already be in place, only their visibility will be limited). He confirmed that "Recalculate Style" only starts when the element becomes visible (which makes sense, actually).

+6
source share
1 answer

The problem seems to be related to li elements that have display:list-item

If you use div elements instead of ul / li , it works pretty fast in chrome ..

Also creating a css li{display:block;} rule li{display:block;} fixes the delay.

And manually adding a list-item shows a delay, even if the items are already mapped to the DOM (they need to be re-mapped)

See demo at http://jsfiddle.net/6D7sM/1/

(therefore, it seems that chrome is slower in rendering display:list-item elements)


There is also a corresponding error for chrome http://code.google.com/p/chromium/issues/detail?id=71305 , which was merged into http://code.google.com/p/chromium/issues/detail? id =% 2094248 (it looks like in earlier versions it was crashing chrome, but it is fixed, crashing, not speed)

+7
source

Source: https://habr.com/ru/post/957447/


All Articles