Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficiently removing textnodes from the DOM

Tags:

javascript

dom

Without getting into too many details, I'm cleaning up whitespace inside tables using javascript. I need to remove large amounts of textnodes. This seems to be the bottleneck in my script when it comes to IE9.

All of the following methods do the job, but they cause a tremendous slow-down.

domNode.removeNode(true);
domNode.nodeValue = "";
domNode.parentNode.removeChild(domNode);

Is there a way to do a bulk remove or a way to hide them in the dom or such. Just something faster.

I've also tried this on the textnodes:

domNode.innerHTML = '';

While it executes quickly, the textnodes seem to be unphased by it.

Also, I need to retain the event bindings so a .innerHTML replace on the whole table doesn't really seem like an option. Though it does run about 5 times faster.

Update: Rough benchmarks on suggested solutions:

//around 480ms
stripWhitespaceTextNodes(domNode);

//around 640ms
parent.removeChild(domNode);
stripWhitespaceTextNodes(domNode);
parent.insertBefore(domNode, nextNode);

//around 700ms
tables[i].style.visibility = 'hidden';
stripWhitespaceTextNodes(domNode);
tables[i].style.visibility = 'visible';

//around 1140ms
tables[i].style.display = 'none';
stripWhitespaceTextNodes(domNode);
tables[i].style.display = 'block';

This was done on 4 tables with one table having 1500 rows.

The crux of the stripWhitespaceTextNodes() function is removing text nodes, this seems to be the bottleneck and here are my various attempts at it.

domNode.parentNode.removeChild(domNode);
domNode.removeNode(true);
domNode.nodeValue = ""; // <-- CURRENTLY THIS ONE IS THE TOP RUNNER
domNode.replaceWholeText('');
domNode.deleteData(0, domNode.length);

var txtNode = document.createTextNode("");
domNode.parentNode.replaceChild(txtNode, domNode);
parent.insertBefore(domNode, nextNode);

//fast but doesn't work
domNode.innerHTML = '';
like image 317
Serhiy Avatar asked Jun 06 '12 08:06

Serhiy


People also ask

How do I get rid of TextNode?

Set the variable y to be the text node to remove. Remove the element node by using the removeChild() method from the parent node.

How do you remove all children from an element?

To remove all child nodes of an element, you can use the element's removeChild() method along with the lastChild property. The removeChild() method removes the given node from the specified element. It returns the removed node as a Node object, or null if the node is no longer available.

How do you clear a DOM element?

To empty a DOM element, set the element's textContent property to an empty string, e.g. element. textContent = '' . Setting textContent on the element removes all of its children and replaces them with a single text node of the provided value.

How do you get rid of child nodes?

Child nodes can be removed from a parent with removeChild(), and a node itself can be removed with remove(). Another method to remove all child of a node is to set it's innerHTML=”” property, it is an empty string which produces the same output. This method is not preferred to use. Example-1: Using “removeChild()”.


1 Answers

The usual trick for this is to remove the container on which you're performing these operations from the DOM before doing the big changes, and then put it back when you're done.

So in your case, that might be:

var table = /* ...get a reference to the table...*/;
var nextNode = table.nextSibling; // May be null, that's fine
var parent = table.parentNode;
parent.removeChild(table);
/* ...clean up the text nodes... */
parent.insertBefore(table, nextNode);

Event handlers remain attached even when the tree is detached from the page's DOM, so they'll be there when the tree is put back.

like image 79
T.J. Crowder Avatar answered Sep 25 '22 03:09

T.J. Crowder