jQuery page freezing while updating DOM with big amount of data

5.6k Views Asked by At

I have a jQuery post method whicih looks like this:

$.post("/SearchCompetitor/Index", { username: _username }, StartLoading())
                           .done(function (data) {
                               if (data !== "UsernameError") {
                                   StopLoading();
                                   var brands = $('<table />').append(data).find('#tableProducts').html();
                                   $('#tableProducts').html(brands);
                                   $("#tableProducts").simplePagination({

                                       // the number of rows to show per page
                                       perPage: 10,

                                       // CSS classes to custom the pagination
                                       containerClass: '',
                                       previousButtonClass: '',
                                       nextButtonClass: '',

                                       // text for next and prev buttons
                                       previousButtonText: 'Previous',
                                       nextButtonText: 'Next',

                                       // initial page
                                       currentPage: 1

                                   });
                                   var header = $('<div />').append(data).find('.bs-glyphicons').html();
                                   $('.bs-glyphicons').html(header);
                                   $('#tableProducts thead, #header').fadeIn("slow");
                                   $('#emptyText').hide();

                               }
                               else {
                                   StopLoading();
                                   ShowMessage("No eBay user was found under: " + $('.txtSearch').val());
                               }
                           })
                           .fail(function (data) {
                               StopLoading();
                               ShowMessage("Something went wrong, please try again!");
                           });

When the post data object doesn't contains a lot of items inside then its fairly okay and it loads without problems...

But when I'm updating the table with 2000+ items inside, it presents a huge issue, I was testing it on firefox browser and it literally crashes every time I work with 2000 + returned items...

My question is, is there any way to avoid browser freezing, maybe some "client side async method" like C# has when using async method to prevent user UI from freezing when working with big chunks of data??

2

There are 2 best solutions below

10
On BEST ANSWER

As mentioned in my comment, reducing the amount of records you are injecting into the DOM would probably be the first thing to address (who really wants a single web page with 2000+ records displayed on it). Using pagination (as you say you are working on) will go a long way towards solving the issue.

Second, be very careful about DOM injection points - - try to decrease the frequency with which you modify the DOM as this is a well known bottleneck.

A very effective way to decrease DOM injection is to work with string data and manipulate the string until it is ready to be used in the DOM. Only at that point would you inject it. Also, NEVER inject to the DOM in a loop.

So, what I see in your code that stands some scrutiny is this:

StartLoading() // <-- you are invoking the function with this code

This should be a function reference, not a function call, so the line should be:

$.post("/SearchCompetitor/Index", { username: _username }, StartLoading)

Next, we have this:

var brands = $('<table />').append(data).find('#tableProducts').html();
$('#tableProducts').html(brands);

First, you are appending your AJAX result directly into the DOM and then you are searching what you've just appended (searching the DOM) for the content of #tableProducs. I would suggest you search the data for what you need before appending it into the DOM:

// Find what you need without injecting it into the DOM so you don't
// have to search the DOM for it:
var brands = $(data).find('#tableProducts').html();

// Just append what you need when you need it:
$('<table />').append(brands);

You have this same scenario a bit later in your code with this:

var header = $('<div />').append(data).find('.bs-glyphicons').html();

Again, search the data for what you need BEFORE injecting it into the DOM.

Lastly, consider whether you should be using .html() or .text(). The former causes the content to be parsed by the HTML parser and the latter doesn't. If the content contains markup, yes you will want .html(), but if not, .text() can be faster.

1
On

I had a similar problem updating element that contained 1000+ DIV elements with ajax call: replacing it with mere 300 DIVS froze the browser.

Funnily, the problem doesn't seem to be in amount of fetched elements but in overwriting the element. I solved it by emptying the element first, like in your case

$('#tableProducts').html('');
$('#tableProducts').html(brands);