jQuery 使用大量数据更新 DOM 时页面冻结

jQuery page freezing while updating DOM with big amount of data

我有一个 jQuery post 方法,它看起来像这样:

$.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!");
                           });

当 post 数据对象内部不包含很多项目时,它还不错,加载时没有问题...

但是当我用里面的 2000 多个项目更新 table 时,它出现了一个大问题,我在 firefox 浏览器上测试它,每次我处理 2000 多个返回的项目时它都会崩溃。 ..

我的问题是,有没有什么方法可以避免浏览器冻结,也许某些 "client side async method" 就像 C# 在使用异步方法时防止用户 UI 在处理大块数据时冻结一样? ?

正如我在评论中提到的,减少您注入 DOM 的记录数量可能是首先要解决的问题(谁真的想要一个显示 2000 多条记录的网页) .使用分页(正如您所说的那样)将大大有助于解决问题。

其次,要非常小心 DOM 注入点 - 尽量减少修改 DOM 的频率,因为这是一个众所周知的瓶颈。

减少 DOM 注入的一种非常有效的方法是使用字符串数据并操作字符串,直到它准备好在 DOM 中使用。只有在那个时候你才会注射它。此外,切勿在循环中注入 DOM。

所以,我在您的代码中看到的经过仔细审查的是:

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

这应该是函数引用,而不是函数调用,所以该行应该是:

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

接下来,我们有这个:

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

首先,您将 AJAX 结果直接附加到 DOM 中,然后搜索您刚刚附加的内容(搜索 DOM)#tableProducs。我建议您在 data 中搜索您需要的内容,然后再将其添加到 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);

你稍后在你的代码中有同样的场景:

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

再次,在将其注入 DOM 之前搜索 data 以查找您需要的内容。

最后,考虑您应该使用 .html() 还是 .text()。前者导致内容被 HTML 解析器解析,而后者则不会。如果内容包含标记,是的,你会想要 .html(),但如果没有,.text() 会更快。

我在使用 ajax 调用更新包含 1000 多个 DIV 元素的元素时遇到了类似的问题:仅用 300 DIVS 替换它会冻结浏览器。

有趣的是,问题似乎不在于获取的元素数量,而在于覆盖元素。我通过先清空元素来解决它,就像你的情况一样

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