2

I have a div#parent element which has a few thousand sibling children div#1, div#2, div#3 like so:

<div id="parent">
  <div id="1"> </div>
  <div id="2"> </div>  
  <div id="3"> </div>  
  …
  …
  …
  <div id="N"> </div>
</div> 

What is the best way to remove all children of the parent node -- preferably asynchronously or through a separate process?

Here are a few standard answers from the wild that deal with slow and fast, but not async/e̶f̶f̶i̶c̶i̶e̶n̶t̶l̶y̶ or non-blocking:

Option 1:

var myNode = document.getElementById("foo");
myNode.innerHTML = '';

Option 2:

let parentNode = document.getElementById("parent");
while (parentNode.firstChild) {
    parentNode.removeChild(parentNode.firstChild);
}

Since a while-loop gives a "busy state" in the dom's single threaded environment I wonder if there is a possibility to remove the nodes from the dom asynchronously/e̶̶̶f̶̶̶f̶̶̶i̶̶̶c̶̶̶i̶̶̶e̶̶̶n̶̶̶t̶̶̶l̶̶̶y̶ or in a non-blocking fashion?

Community
  • 1
  • 1
Marvin Danig
  • 3,738
  • 6
  • 39
  • 71
  • 4
    Wouldn't it be better to avoid producing thousands of `div` tags in the first place? – trincot Aug 31 '16 at 21:05
  • Does `myNode.innerHTML = '';` not return expected result? What do you mean by "Asynchronously remove children"? – guest271314 Aug 31 '16 at 21:08
  • That's just the structure currently, it usually stays at a few hundred such elements, but can go up to a 1000 elements or so depending on the length of a write up. – Marvin Danig Aug 31 '16 at 21:10
  • @guest271314 meaning like on a web-worker (it doesn't have access to dom though) or in node environment or with promises(). – Marvin Danig Aug 31 '16 at 21:12
  • 3
    What makes you think it needed to be asynchronous to be "efficient"? – Bergi Aug 31 '16 at 21:16
  • @marvindanig _"meaning like on a web-worker "_ Not certain what you mean? Remove elements from `document` calling web worker within web worker? What are you trying to achieve? – guest271314 Aug 31 '16 at 21:16
  • 1
    here are some async foreach loops, not sure how performant they are though https://h3manth.com/content/async-foreach-javascript – mzmm56 Aug 31 '16 at 21:45
  • @bergi fixed to non-blocking instead of efficient. :-) – Marvin Danig Aug 31 '16 at 21:52
  • What is issue with using "Option 1" `.innerHTML = ""`? Is requirement to remove element one at a time? – guest271314 Aug 31 '16 at 21:55
  • @guest271314 it could be the straightforward answer, I'm just bouncing it off right now given newer patterns out there. – Marvin Danig Aug 31 '16 at 21:58
  • 1
    @marvindanig: You might want to have a look at [this list of links](http://stackoverflow.com/a/10809905/1048572) about non-blocking loops – Bergi Aug 31 '16 at 22:01
  • 1
    @marvindanig If requirement is not to remove elements one at a time `.innerHTML = ""` would return expected result; another pattern is not necessary – guest271314 Aug 31 '16 at 22:03

1 Answers1

4

Obviously innerHTML = '' will remove all items simultaneously. If this is too slow and you want to remove the elements little by little, then you need something similar to your second approach.

let parentNode = document.getElementById("parent");
(function remove() {
  // Remove elements in groups of 100
  for(let i=0; i<100 && parentNode.firstChild; ++i) {
    parentNode.removeChild(parentNode.firstChild);
  }
  // Continue asynchronously after 50ms
  setTimeout(remove, 50);
})();

Adjust the group size and the time delays as needed.

Oriol
  • 274,082
  • 63
  • 437
  • 513