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

Use*_*987 1 javascript c# jquery asynchronous freeze

我有一个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!");
                           });
Run Code Online (Sandbox Code Playgroud)

当post数据对象里面没有很多项目时,它相当没问题,加载没有问题......

但是当我用2000+项目更新表格时,它提出了一个很大的问题,我在firefox浏览器上测试它,每次我使用2000 +返回项目时它都会崩溃...

我的问题是,有没有办法避免浏览器冻结,也许一些像C#一样的"客户端异步方法"在使用异步方法时阻止用户UI在处理大块数据时冻结?

Sco*_*cus 6

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

其次,要非常小心DOM注入点 - 尝试降低修改DOM的频率,因为这是众所周知的瓶颈.

减少DOM注入的一种非常有效的方法是使用字符串数据并操作字符串,直到它准备好在DOM中使用.只有在这一点上你会注射它.此外,永远不要在循环中注入DOM.

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

StartLoading() // <-- you are invoking the function with this code
Run Code Online (Sandbox Code Playgroud)

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

$.post("/SearchCompetitor/Index", { username: _username }, StartLoading)
Run Code Online (Sandbox Code Playgroud)

接下来,我们有这个:

var brands = $('<table />').append(data).find('#tableProducts').html();
$('#tableProducts').html(brands);
Run Code Online (Sandbox Code Playgroud)

首先,您将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);
Run Code Online (Sandbox Code Playgroud)

您稍后在代码中使用相同的方案:

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

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

最后,考虑一下你是否应该使用.html().text().前者导致内容由HTML解析器解析而后者不解析.如果内容包含标记,那么您将需要.html(),但如果不包含,.text()则可以更快.

  • `$("div")`不创建元素,但引用现有的`"div"元素.`"div"`是一个选择器,`"<div />"`或``<div> </ div>"`创建一个新的`<div>`元素. (2认同)