【问题标题】:How to append (massively) multiple elements to the DOM using jQuery如何使用 jQuery 将(大量)多个元素附加到 DOM
【发布时间】:2019-06-05 00:55:09
【问题描述】:

我有一个必须由 API 的异步响应动态填充的表。 API 发回一个 JSON,该 JSON 稍后被解释为表格的一行,我让它完美运行。

问题是,JSON 响应越大,处理响应所需的时间就越多(显然),所以当我在数组中超过 2k-3k 个元素时,将行追加到表中的 JS 开始处理 JSON 响应的时间超过 20 分钟。

有什么办法可以优化吗?

以下是我的解析过程示例:

function fillTable() {
    let tbody = $('tbody');
    for(let i = 0; i < 100; i++) {
        let tr = $('<tr><td>' + (i + 1) + '</td><td>Table row ' + (i + 1) + '</td><td>' + (Math.random() * 1000) + '</td></tr>');
        tr.appendTo(tbody);
    }
}
fillTable();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
    <thead>
        <tr>
            <th>#</th>
            <th>Description</th>
            <th>Value</th>
        </tr>
    </thead>
    <tbody>
    </tbody>
</table>

显然,sn-p 并不反映处理 JSON 所需的时间量,但你明白了。

【问题讨论】:

  • 优化问题多与codereview.stackexchange.com相关
  • 从等式中删除 jQuery 并立即添加行(tbody.insertAdjacentHTML(...)tbody = document.createElement("tbody"); /*...*/ tbody.appendChild(row); table.appendChild(tbody);,...)
  • 我投票决定将此问题作为离题结束,因为该问题提供了一个有效的代码示例,并提供了一种优化它的方法。鉴于原始逻辑有效,并且有多种方法可以优化此逻辑以促进固执己见的答案,这个问题对于 StackOverflow 来说是题外话,并且更适合像 CodeReview 这样的相关站点,其中重构将成为主题。
  • @GeorgeJempty 问题被标记为可能重复的链接大约有 10 个新元素。针对该问题提出的答案并不能解决 2k-3k 元素的性能问题。

标签: javascript jquery html dom optimization


【解决方案1】:

我解决这个问题的方法是,不是将每一行单独附加到表中,而是将每个行元素推送到一个数组中,并在数组完成后,使用 apply 原型函数,扩展 append jQuery函数以便一次应用整个数组。

像这样:

function fillTable() {
    let tr = [];
    let tbody = $('tbody');
    for(let i = 0; i < 100; i++) {
        let e = $('<tr><td>' + (i + 1) + '</td><td>Table row ' + (i + 1) + '</td><td>' + (Math.random() * 1000) + '</td></tr>');
        // Removed for better performance
        //tr.appendTo(tbody);
        tr.push(e);
    }
    $.fn.append.apply(tbody, tr).html();
}

因此,将 11k 条记录的 20-40 分钟流程减少到大约 7 秒。

【讨论】:

  • 关于这个答案的一些事情令人困惑。 tr 以数组开始,但随后循环执行 tr.appendTo(tbody)appendTo() 是 jQuery 方法,而不是数组方法。所以这似乎是一个错误。此外,如果您只是将新元素推送到数组tr.push(e) 比使用tr = [...tr, ...e]; 构造一个全新的数组要干净得多。最后,tbody 是一个 jQuery 对象。 tbody.append(tr) 会将所有元素附加到 tbody。 $.fn.append.apply(tbody, tr) 操作过于复杂,下面的html() 调用未使用。
  • 如果你想获得更高的性能,你不会做$(html)而只是构建html。
  • 对不起。通过注释 appendTo() 块来修复它。逐个添加元素大大增加了 HTML 解析过程,这是我通过一次调用 $.fn.append.apply 解决的问题。 tr.push(e) 的性能是否优于 [...tr,...e]?如果是这样,我不知道这一点,可能会在我的代码中更改它。
  • 为什么构造一个全新的数组比重用同一个数组、推送新元素的性能更好?
  • 我不能只构建 HTML,因为它是对 API 的动态调用,它本身在站点的多个部分中被调用。相同的响应用于构建具有不同结构的其他表。
【解决方案2】:

您可以使用分页创建无限加载和逐步加载。

function fillTable(page) {
    let tbody = $('tbody');
    for(let i = page; i < page + 50; i++) {
        let tr = $('<tr><td>' + (i + 1) + '</td><td>Table row ' + (i + 1) + '</td><td>' + (Math.random() * 1000) + '</td></tr>');
        tr.appendTo(tbody);
    }
}
fillTable(5);

但你需要有滚动页面的控制权

【讨论】:

    猜你喜欢
    • 2017-03-25
    • 2019-05-24
    • 1970-01-01
    • 2020-11-25
    • 2013-06-01
    • 2014-03-10
    • 2016-07-24
    • 1970-01-01
    • 2014-12-26
    相关资源
    最近更新 更多