Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Speeding up jQuery empty() or replaceWith() Functions When Dealing with Large DOM Elements

Let me start off by apologizing for not giving a code snippet. The project I'm working on is proprietary and I'm afraid I can't show exactly what I'm working on. However, I'll do my best to be descriptive.

Here's a breakdown of what goes on in my application:

  1. User clicks a button
  2. Server retrieves a list of images in the form of a data-table
  3. Each row in the table contains 8 data-cells that in turn each contain one hyperlink
    • Each request by the user can contain up to 50 rows (I can change this number if need be)
    • That means the table contains upwards of 800 individual DOM elements
    • My analysis shows that jQuery("#dataTable").empty() and jQuery("#dataTable).replaceWith(tableCloneObject) take up 97% of my overall processing time and take on average 4 - 6 seconds to complete.

I'm looking for a way to speed up either of the above mentioned jQuery functions when dealing with massive DOM elements that need to be removed / replaced. I hope my explanation helps.

like image 590
Levi Hackwith Avatar asked Jun 12 '09 17:06

Levi Hackwith


2 Answers

jQuery empty() is taking a long time on your table because it does a truly monumental amount of work with the contents of the emptied element in the interest of preventing memory leaks. If you can live with that risk, you can skip the logic involved and just do the part that gets rid of the table contents like so:

    while ( table.firstChild )
        table.removeChild( table.firstChild );

or

    table.children().remove();
like image 86
chaos Avatar answered Oct 26 '22 23:10

chaos


I recently had very large data-tables that would eat up 15 seconds to a minute of processing when making changes due to all the DOM manipulation being performed. I got it down to <1 second in all browsers but IE (it takes 5-10 seconds in IE8).

The largest speed gain I found was to remove the parent element I was working with from the DOM, performing my changes to it, then reinserting it back into the DOM (in my case the tbody).

Here you can see the two relevant lines of code which gave me huge performance increases (using Mootools, but can be ported to jQuery).

update_table : function(rows) {
    var self = this;
    this.body = this.body.dispose();  //<------REMOVED HERE
    rows.each(function(row) {
        var active = row.retrieve('active');
        self.options.data_classes.each(function(hide, name) {
            if (row.retrieve(name) == true && hide == true) {
                active = false;
            }
        });
        row.setStyle('display', (active ? '' : 'none'));
        row.store('active', active);
        row.inject(self.body);   //<--------CHANGES TO TBODY DONE HERE
    })
    this.body.inject(this.table);  //<-----RE-INSERTED HERE
    this.rows = rows;
    this.zebra();
    this.cells = this._update_cells();
    this.fireEvent('update');
},
like image 29
TJ L Avatar answered Oct 27 '22 00:10

TJ L