【问题标题】:using jquery, how can i speed up appending a list onto a selector使用 jquery,我如何加快将列表附加到选择器上
【发布时间】:2011-12-04 04:04:27
【问题描述】:

我的以下代码看起来很慢,我想看看是否有任何其他方法可以更快地转储这些数组。

$.get("/MyController/GetDates?month=1&year=2011", function (data) {

        $.each(data.VacationEvents, function (index, value) {
            $("#vacationDates").append('<p>' + value.Date + '</p>');
        });
        $.each(data.CalendarEvents, function (index, value) {
            $("#calendarDates").append('<p>' + value.Date + '</p>');
        });
        $.each(data.ReleaseEvents, function (index, value) {
            $("#releasenDates").append('<p>' + value.Date + '</p>');
        });
    });

【问题讨论】:

    标签: jquery asp.net-mvc performance append


    【解决方案1】:

    每次修改连接的 DOM 节点时,都会强制浏览器重排文档。请参阅来自10 Javascript Performance Boosting Tips 的#9。

    解决方案:

    • 创建将包含生成的 HTML 的 innerHTML 变量。
    • .each() 中附加 HTML。
    • innerHTML 附加到#vacationDates
    • #calendarDates#releasenDates 执行相同操作。

      // ...
      var innerHTML = "";
      $.each(data.VacationEvents, function (index, value) {
         innerHTML += '<p>' + value.Date + '</p>';
      });
      $("#vacationDates").append(innerHTML);
      // ...
      

    【讨论】:

      【解决方案2】:

      我会创建一个数组,然后将它一次附加到元素上。我怀疑它太慢了,因为每次追加都必须更新 DOM,所以这样你只需要更新 DOM 3 次。

      var dates = [];
      $.each(data.VacationEvents, function (index, value) {
           dates.push('<p>' + value.Date + '</p>');
      });
      $("#vacationDates").append(dates.join(''));
      

      此外,如果您创建一个二维数组,您可以存储实际日期以及文本,然后如果您还持有对日期数组的引用,您可以轻松地允许用户在客户端按日期排序一边。

      【讨论】:

        【解决方案3】:

        最好尽量减少 DOM 操作,因此不要在循环中使用.append()ing,而是构建元素集然后附加它们。避免循环函数也更快,只需使用for 循环。像这样的:

        $.get("/MyController/GetDates?month=1&year=2011", function (data) {
        
            var vacationEvents = data.VacationEvents;
                $newVacations = $();
        
            for (var i=0; i<vacationEvents.length; i++) {
                $newVacations.add($('<p></p>', {text: vacationEvents[i].Date}));
            }
        
            $newVacations.appendTo("#vacationDates");
        
            // etc
        });
        

        【讨论】:

        • 此方法的其他建议变体可能更快,但思路相同。
        【解决方案4】:

        “更快”是什么意思?只是更精简或更少的代码行?也许是这样的?

        $.get("/MyController/GetDates?month=1&year=2011", function (data) {
        
            var myData = ['Vacation','Calendar','Release'];
            for(var i=0; i<myData.length; i++) {
                $.each(data[myData[i]], function(index, value) {
                    $("#" + myData[i] + "Dates").append('<p>' + value.Date + '</p>');
                });
            }
        });
        

        【讨论】:

        • 我认为 OP 的意思是“执行速度更快的代码”,而不是“更简洁的代码”。
        • @MДΓΓБДLL 这有点不清楚,所以我不确定。好吧,其他人提供的任何解决方案也可以与此结合使用。
        【解决方案5】:

        创建元素而不是附加文本 html。简短的回答是,这可以防止您的浏览器将文本解析为 HTML。更长的answer can be found here

        替换

        $.each(data.VacationEvents, function (index, value) {
            $("#vacationDates").append('<p>' + value.Date + '</p>');
        });
        

        $.each(data.VacationEvents, function (index, value) {
            vacation_date = document.createElement('p');
            vacation_date.innerHTML = value.Date; /* it pains me to do this */
            $("#vacationDates".append(vacation_date);
        });
        

        【讨论】:

        • innerText 在 Firefox 中不起作用;必须在那里使用textContent
        • 感谢您的提醒,正在更改。
        • textContent 在 IE8 及更低版本中不起作用。必须在那里使用innerText。 ;)
        • 是的,但是♫我对 IE 来说太性感了♫。
        猜你喜欢
        • 2014-03-15
        • 1970-01-01
        • 2021-10-24
        • 2013-11-08
        • 1970-01-01
        • 2014-12-30
        • 1970-01-01
        • 2021-02-15
        • 1970-01-01
        相关资源
        最近更新 更多