Why does removing elements take more time than adding elements?
I'm assuming you have bad performance on IE.
I'd say that's because the $.empty
method calls removeChild
in a loop for every removed element in the table and that method always had bad performance in IE - see this article for short case study with some performance comparisons and resolutions.
No matter what you do with large DOM you will have bad performance on IE. This article on appendChild in large DOM on IE is an example of how the community is still befuddled by this simple fact. :)
If you ask why emptying the table should take 1000 times longer than appending it, well, it just shouldn't: that is a bug.
You can find important performance differences depending on the browser, its version, the version of jQuery or the OS, but 25s vs 23ms is way too much. It seems than somewhere you hit a O(N^2)
operation. For less than that people open tickets and the browser's developers acknowledge them.
Anyway, removing elements its not always faster that adding them. Our intuition says that destroy should be faster than create but that's not necessarily true when it comes to manipulate the DOM. Both jQuery and the browser need to make additional work to take elements out.
If you have a look to the current (3.2.1) implementation of jQuery append()
function you will see that what it basically does is to use the native JS method appendChild()
. On the other hand jQuery empty()
function (html()
uses empty()
) needs to loop over all the inner elements and take care of removing the related data (e.g. events) to each of the inner elements to prevent memory leaks.
And, if you use just vanilla JS, the browser still needs to check a big bunch of things when removing elements. If you want to get into the browser's internals you can check this Firefox issue.
It doesn't matter if you go for removeChild()
, innerHtml
or textContent()
, the browser always need to recalculate styles and layout: check this one in Chromium.
This kind of bugs are common. If you search into the Chromium for issues with the keywords "removeChild" and "slow" you get a pretty long list. Sometimes they come and go due to fixes introducing regressions, like in this case involving floating elements. This other one can be specially interesting for you, because it proofs that some bugs are not connected with the method you choose to remove the elements and because, like in your case, it shows up when complex CSS rules are applied to that elements (suggesting than the browser triggered a reflow).
I was unable to reproduce your issue neither in Firefox nor in Chrome, so I can't address the exact reason for the 25 seconds or 1.5 minutes, but it really seems to a bug fixed in more recent versions. If you still have the same old version and can reproduce it, it could be worth to check if removing the elements in inverse order (starting from lastChild
) helps. Perhaps you avoid recalculating the position of all the floating siblings after the one you remove.
Next time maybe you want to open a ticket and follow how they find the bug and fix it. It will satisfy your curiosity and you can learn a lot about browser internals!