技术频道导航
HTML/CSS
.NET技术
IIS技术
PHP技术
Js/JQuery
Photoshop
Fireworks
服务器技术
操作系统
网站运营

赞助商

分类目录

赞助商

最新文章

搜索

将元素(element)追加(append)到DOM的最快方法

作者:admin    时间:2022-7-19 10:7:11    浏览:

使用JavaScript或jQuery将元素(element)追加(append)到DOM,是前端开发人员常常用到的技术,不过虽然方法多种多样,你可能不知道哪种方法才是最快最有效的。在本文中,将通过对比多种实现方法,找出最快最有效的方法。

本文演示中,我们假设我们的任务是将 10,000 个 div 附加到网页的正文中。

1、最简单直接的方法

大多数人,会这样做:

for (var i=0; i<10000; i++) {
  $("BODY").append($("<div />").addClass("test-div"));
}

这种方法简单直接明了,所以大家都喜欢使用。

此代码产生的平均运行时间为779.463ms。这意味着将这些元素附加到 DOM 需要超过四分之三秒的时间。

那么这里的问题是什么?

好吧,有一些 - 太多的重排和太多的 jQuery 对象。我们将在下一步中解决后者,所以让我们在这里看看回流。

简单来说,reflow就是浏览器需要对网页进行处理和绘制的时候,是最昂贵的浏览器进程之一。提高应用程序性能的最简单方法之一是尽量减少回流次数,这就是我们要做的。

许多不同的操作都可能导致回流,并且对于每个浏览器来说都不一样。将元素附加到 DOM 会导致重排。因此,我们的代码片段的明显问题是我们正在生成 10,000 次回流。有些浏览器可能会智能地处理这个问题并降低一些成本,但我们可以做得更好。

2、修复回流问题

让我们通过创建一个尚未添加到 DOM 的节点来解决我们的回流问题。然后我们将把我们的 div 附加到这个节点上。最后,我们会将这个单个节点附加到应该触发单个回流的 DOM 中。

var $c = $("<div />").addClass("container");
for (var i=0; i<10000; i++) {
    $c.append($("<div />").addClass("test-div"));
}
$("BODY").append($c);

代码平均运行时间现在是432.524ms。这有点好,但仍然不是很好,我们可以做很多改进。

这里的问题是我们仍然创建了太多的 jQuery 对象。即使我们已经解决了重排问题,创建 jQuery 对象还是有很多开销。当然,对于单个对象,jQuery 的便利性远远超过了对性能的最小影响。但是,如果我们要处理 10,000 个元素,那么效率低下的情况就非常明显了。

让我们看看当我们完全跳过使用 jQuery 并用纯 JavaScript 编写它时会发生什么。

var c = document.createDocumentFragment();
for (var i=0; i<10000; i++) {
    var e = document.createElement("div");
    e.className = "test-div";
    c.appendChild(e);
}
document.body.appendChild(c);

令人难以置信的是,这种变化将我们的总运行时间从432.524ms 减少到了16.237ms。这是有道理的,因为创建对象实际上需要 jQuery 一些时间。让我们看看创建单个 jQuery 对象与使用原生 JavaScript 创建元素需要多长时间。

console.time("jquery div");
var jqDiv = $("<div />");
console.timeEnd("jquery div");
// jquery div: 0.272ms

console.time("js div");
var jsDiv = document.createElement("div");
console.timeEnd("js div");
// js div: 0.006ms

这是一个显着的差异 - 0.006ms0.272ms。这种比较的目的并不是说 jQuery 不好,而是作为开发人员你应该知道什么时候使用它,什么时候不使用它。jQuery 提供了很多我们不需要的功能,因此以如此高的成本创建 10,000 个 jQuery 对象是没有意义的。

3、使用字符串而不是节点

我们实际上不必创建 10,000 个节点。相反,我们可以看到当我们使用一长串 HTML 时会发生什么。

var s = "";
for (var i=0; i<10000; i++) {
    s += "<div class=\"test-div\"></div>";
}
$("BODY").append(s);

运行时间需要69.874ms,它的性能比我们原来的要好得多,但不如纯 JavaScript 版本好。但是,我们可以做一点小改进。字符串连接很昂贵,尤其是在这种规模下。让我们使用一个字符串数组并将它们连接到最后。

var a = [];
for (var i=0; i<10000; i++) {
    a.push("<div class=\"test-div\"></div>");
}
$("BODY").append(a.join(""));

63.885ms。这可能不足以改善压力,但由于它更快,我们会保留它。

让我们测量一下使用 jQuery 附加字符串的成本。正如我们在上一步中了解到的,使用纯 JavaScript 可能会更快。

var a = [];
for (var i=0; i<10000; i++) {
    a.push("<div class=\"test-div\"></div>");
}
document.body.innerHTML = a.join("");

这里的主要区别是我们没有使用 jQuery.append。相反,我们将 body 上的 innerHTML 属性设置为我们的 HTML 字符串。代码运行需要22.908ms,因此改进是显而易见的。但是我们仍然没有上一步的纯 JavaScript 版本那么快。

4、结论

总之,最快的代码是纯 JavaScript 版本:

var c = document.createDocumentFragment();
for (var i=0; i<10000; i++) {
    var e = document.createElement("div");
    e.className = "test-div";
    c.appendChild(e);
}
document.body.appendChild(c);

基于这些实验,有两个主要结论。

首先,要注意哪些操作会导致回流。这是一个昂贵的过程,应该尽可能减少。

其次,要注意使用 jQuery 的成本。对于小规模的操作,jQuery 的便利性往往会超过性能成本。但是在大范围内,除非确实需要,否则应该避免使用 jQuery。

相关文章

标签: element  append  DOM  
x
  • 站长推荐
/* 左侧显示文章内容目录 */