使用文档片段真的能提高性能吗?

2024-04-21

我对 JS 的性能有疑问。

比如说,我有下一个代码:

var divContainer = document.createElement("div"); divContainer.id="container";
var divHeader = document.createElement("div"); divHeader.id="header";
var divData = document.createElement("div"); divData.id="data";
var divFooter = document.createElement("div"); divFooter.id="footer";
divContainer.appendChild( divHeader );
divContainer.appendChild( divData );
divContainer.appendChild( divFooter );
document.getElementById("someElement").appendChild( divContainer );

这段代码只是为其他一些函数创建了 shell 来创建网格,创建网格的过程非常复杂并且需要进行许多验证,目前我使用 2 种方法来填充网格,一种在数组变量中创建整个 html另一个创建元素并将它们附加到documentFragment.

我的问题是,正如我所理解的那样,使用片段时性能是否真的有所改善——它们管理内存上的元素,因此它们不会附加到文档中,因此不会触发 DOM 重新计算和其他令人讨厌的东西。但我创建变量的方式是,在我将容器附加到实际页面之前,它们不会附加到任何 DOM 元素。

所以我想知道前面的代码是否比使用将其全部包装起来的文档片段具有更好的性能,如下所示:

var fragment = document.createDocumentFragment();
var divContainer = document.createElement("div"); divContainer.id="container";
var divHeader = document.createElement("div"); divHeader.id="header";
var divData = document.createElement("div"); divData.id="data";
var divFooter = document.createElement("div"); divFooter.id="footer";
divContainer.appendChild( divHeader );
divContainer.appendChild( divData );
divContainer.appendChild( divFooter );
fragment.appendChild( divContainer )
document.getElementById("someElement").appendChild( fragment.cloneNode(true) );

正如我已经说过的,这是一个关于性能的问题,我知道作为最佳实践,建议使用片段,但我无法摆脱这样的想法:这样做只会在内存中创建一个新对象,并且不执行任何操作,因此我认为在这种情况下放弃片段是有效的。

希望一些 js 大师/上帝能够在这里点亮希望之光并帮助我们解决这个问题。


Edit:所以,我一直在寻找与这个问题相关的东西,似乎 documentFragments 并不一定意味着更好的性能。

它只是节点的“内存中”容器。片段和片段之间的区别<div>其特点是该片段没有父级,并且永远不会在 DOM 上,而只是在内存中,这意味着对片段进行的操作速度更快,因为无需对 DOM 进行操作。

W3C http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-B63ED1A3关于 documentFragments 的文档非常模糊,但很重要,而且每个人最喜欢的浏览器并不使用真正的片段,而是根据这个 MSDN 文档 http://msdn.microsoft.com/en-us/library/ms536387%28VS.85%29.aspx。这意味着 IE 上的片段速度较慢。

那么,问题就来了,如果我创建一个元素 (a <div>例如)在变量中但不要将其附加到 DOM,添加元素(div、表格等)以及所有工作完成后(循环、验证、元素样式),该元素被附加,它与片段相同吗?


文档片段 is 快多了当它用于插入一个元素集 in 多个地方。这里的大多数答案都指出了它的无用,但这是为了证明它的力量。

让我们举个例子。

假设我们需要附加20 divs in 10个元素与类容器.

Without:

var elements = [];
for(var i=20; i--;) elements.push(document.createElement("div"));

var e = document.getElementsByClassName("container");
for(var i=e.length; i--;) {
  for(var j=20; j--;) e[i].appendChild(elements[j].cloneNode(true));
}


With:

var frag = document.createDocumentFragment();
for(var i=20; i--;) frag.appendChild(document.createElement("div"));

var e = document.getElementsByClassName("container");
for(var i=e.length; i--;) e[i].appendChild(frag.cloneNode(true));

对我来说,在 Chrome 48 上使用文档片段的速度提高了 16 倍。

在 JsPerf 上测试 http://jsperf.com/document-fragment-test-peluchetti/38

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用文档片段真的能提高性能吗? 的相关文章

随机推荐

  • 使用两个具有相同命名空间的 .NET 库

    我目前正在为一家公司维护一些旧代码 正如所发生的那样 我正在修改的当前应用程序使用旧版本的内部库 我们将其称为 Lib1 dll 他们还有一个名为 Lib2 dll 的新版本库 它在许多方面对以前的库进行了改进 不幸的是 Lib2 不向后兼
  • VBS 脚本 getElementbyID 错误(自动登录脚本)

    我正在编写适用于不同站点的 vbs 脚本文件 但我正在为我的大学网页编写用于互联网页面登录的自动登录脚本 所以我一直在工作直到填写用户名和密码 但我无法让它点击登录 这是大学登录的链接 我不确定您是否可以从网络外访问它 请注意编辑请不要将其
  • 从 DataReader 读取数据的通用方法

    我目前正在使用此方法从 DataReader 读取数据 private T GetValue
  • LinkedList“节点跳转”

    试图找出为什么我的list 类指针被第三个节点覆盖 插入函数 如下 中发生的情况是 第三次调用插入函数headByName gt nextByName当第三个节点应该指向第二个节点时 节点指针被第三个节点覆盖 因此 您可以猜测第 4 个节点
  • 使用 Velocity 生成基于 HTML 的电子邮件

    我尝试这个教程http www java2s com Code Java Velocity UseVelocitytogenerateHTMLbasedemail htm http www java2s com Code Java Velo
  • Tensorflow:加载预训练 ResNet 模型时出错

    我想使用 Tensorflow 中预先训练的 ResNet 模型 我下载了code https github com tensorflow models blob master research slim nets resnet v1 py
  • 如何在 Qt 中实现 QHoverEvent?

    我正在学习 Qt 和 C 我已经成功地实现了信号和槽来捕获标准事件 例如ButtonPushed 等等 但是 我希望当我将鼠标悬停在鼠标上并移出鼠标时调用一个函数QLabel 看起来像QHover事件 http doc qt io qt 4
  • Twisted、FTP 和“流式传输”大文件

    我正在尝试实现最能描述为 HTTP API 的 FTP 接口 的内容 本质上 有一个现有的 REST API 可用于管理站点的用户文件 并且我正在构建一个中介服务器 将该 API 重新公开为 FTP 服务器 因此 您可以使用 Filezil
  • 如何正确使用DispatchQueue.main.async?

    我的应用程序中有一个循环 可能需要几秒钟的时间来处理 我希望当循环在后台运行时屏幕立即关闭 这可能吗 我尝试过仅添加循环 DispatchQueue main async for in 1 self numberOfTransactions
  • Maven:从执行元素获取目标配置

    假设我有以下魔力 Mojo name some goal public class MyMojo Parameter required true protected ComplexObject param 另外我在 pom 中有插件的描述符
  • 如何剪辑较大的图像以适合以编程方式构建的 tabBarController 中的 tabBar 图标。

    我以编程方式创建了一个选项卡控制器 现在 我想将图像添加到不同的选项卡 为此我使用了 self tabBarItem image UIImage imageNamed Sample Image png 问题是 Sample image 的大
  • C++ 模板继承问题与基类型

    我有以下代码 但无法编译 template lt typename T gt class Base public typedef T TPtr void func template lt typename T gt class Derive
  • Nexus 工件删除命令

    我已使用以下命令从命令行将工件上传到 Sonatype Nexus MAVEN maven bin mvn X e 部署 部署文件 Durl http maven nexus com nexus content repositories x
  • 将公钥添加到 ~/.ssh/authorized_keys 不会自动登录

    我将公共 SSH 密钥添加到授权密钥 file ssh localhost应该让我登录而不询问密码 我这样做并尝试输入ssh localhost 但它仍然要求我输入密码 我还需要进行其他设置才能使其正常工作吗 我已按照更改权限的说明进行操作
  • MASM32 中令人困惑的括号

    我正在尝试掌握 MASM32 但对以下内容感到困惑 我认为括号用于间接 所以如果我有预定义的变量 data item dd 42 then mov ebx item 会将 item 的内容 即数字 42 放入 ebx 中并 mov ebx
  • 来自卸载事件的同步 AJAX 发布:如何确保用户在下一页加载时看到来自数据库的最新信息

    当用户请求编辑 CMS 中的条目时 我们会 锁定 它 以便其他人无法同时编辑它 当他们提交更改时 我们会释放锁定 然而 我们需要处理用户通过其他链接离开页面的情况 我的第一次尝试是使用 jQuery 来触发同步 ajax 呼吁 window
  • 通过Entity类名动态获取一个DbSet

    我正在尝试使用System Reflections得到一个DbSet
  • 如何使用批处理全屏打开窗口

    我之前用代码制作了一个批处理文件 start chrome exe profile directory Profile 1 http drive google com 它会以配置文件 1 用户的身份打开 google chrome 页面 D
  • 尝试从故事板初始化视图控制器

    我有一个视图控制器放置在主故事板中 但是当我尝试初始化并加载视图控制器时 我的应用程序崩溃了 我使用的 xcode 版本并没有真正告诉我我正确得到的错误 但我确实看到它给了我一个 sigabrt 信号 我不知道为什么它不起作用 UIStor
  • 使用文档片段真的能提高性能吗?

    我对 JS 的性能有疑问 比如说 我有下一个代码 var divContainer document createElement div divContainer id container var divHeader document cr