使用CSS生成的内容(即伪元素)比添加更多DOM元素更有效(即解析/渲染更快)吗?

Big*_*ack 16 css performance dom pseudo-element shadow-dom

为了使我的移动网络应用程序保持精简和高效,我试图在任何给定时间限制DOM上的元素数量.我打算限制DOM元素使用的一种方法是使用伪:before:after元素在可能的情况下生成内容.

例如,而不是像这样表示具有元数据的列表项:

<dd class="item">
    <div class="name">Name</div>
    <div class="desc">Description</div>
    <div class="location">Location</div>
    <div class="genre">Genre</div>
</dd>
Run Code Online (Sandbox Code Playgroud)

我可以这样表示它(并使用content:属性来显示元数据):

<dd class="child" 
    data-name="Name" 
    data-desc="Description" 
    data-location="Location" 
    data-genre="Genre">
</dd>
Run Code Online (Sandbox Code Playgroud)

因此,一个DOM元素具有数据属性,而不是5个单独的元素,可以说是更清晰的标记.
在这里演示:http://jsfiddle.net/quc8b/2/

这种技术真的会提高性能吗?我的想法是,使用更少的DOM元素,javascript应该更快地解析,我应该能够更快地添加/删除列表项节点.但渲染(即绘画,布局和回流)会更快发生吗?换句话说,CSS生成的内容是否比传统元素和文本节点更快或更有效地呈现/解析?

浏览器内部如何处理渲染树和文档树中的CSS生成内容对我来说是未知的(影子DOM可能?).有没有文章可以讨论这个问题?

Drk*_*ima 6

我也有兴趣弄清楚这一点。所以我做了一个简单的测试案例。

我创建了两个html页面进行比较:

A.伪选择器:

  • HTML:其中50.000: <p>paragraph</p>

  • CSS: p:before { display: inline-block; width: 10px; height: 10px; margin-right: 5px; background-color: red; content: ""; }

B.许多DOM元素:

  • HTML:其中50.000: <p><span class="icon"></span> paragraph</p>

  • CSS: .icon { display: inline-block; width: 10px; height: 10px; margin-right: 5px; background-color: red; }


测试:

我使用了在2015 Macbook Pro上运行的Chrome Devtools性能监视器。

Test1:“开始分析并重新加载页面”

选项B在约400ms内是失败者。解析耗时2452毫秒,而“伪”变体耗时2033毫秒。我进行了三次测试,结果相似。

屏幕截图

Test2:调整窗口大小

为了测量重新布局,我开始了一个单独的记录,在其中我通过从全屏更改为半屏(使用窗口管理器中的快捷键)将浏览器窗口的大小调整了3倍。

“许多DOM元素”获得了冠军,渲染时间为1136毫秒,而“伪元素”花费了1463毫秒。

在此处输入图片说明

Test3:回流

我试图通过使用这段Javascript测量页面高度来引起重排: document.body.offsetHeight;

但这花了不到4毫秒的时间来执行...没有足够的时间来可靠地衡量性能。

显然50.000个元素不足以导致该区域的任何显着速度下降。

PS:测试选择并不是那么科学,只是我想到的第一个选择


nir*_*zul -4

请注意,这个答案是几年前给出的。下面列出的许多陈述不再有效。在提供应该可访问的内容时,仍然不鼓励使用伪元素。

我不知道伪元素的性能,但我担心你把性能看得高于一切。

与“真实”DOM 节点相比,伪元素有相当大的缺点:

  • 它们无法进行过渡或动画处理
  • 您无法使用 Javascript 动态更改它们的外观
  • 它们对搜索引擎来说远没有那么“重要”
  • 它们在调试时很麻烦
  • 它们的数量仅限于一个:before和一个:after元素
  • 它们无法包含 HTML 标签,例如链接或其他容器
  • 你伤害了内容和外观分离的概念
  • 某些 HTML 元素不能有伪元素

如需进一步阅读,请参阅Tag-Wiki

我确信还有更多。另一方面是某种性能提升,我认为这种提升可以忽略不计。

  • 它们可以进行转换/动画它们可以使用 JS 更改外观(通过添加类/属性,但这是可能的)。它们在调试中并不麻烦(曾经使用过 Google Chrome 开发者工具吗?)它们可以通过单个 :before 或 :after 包含多个信息,因此每个信息 1 就足够了。不存在内容和外观分离的问题。此外,在许多情况下,性能至关重要,使用 CSS 将某些元素转换为有用的小部件比使用 JS 容易得多,而且不需要清理它 (5认同)
  • 是的,这并不能回答问题。 (4认同)