24

为了让我的移动网络应用程序保持精简和高效,我试图在任何给定时间限制 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>

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

<dd class="child" 
    data-name="Name" 
    data-desc="Description" 
    data-location="Location" 
    data-genre="Genre">
</dd>

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

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

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

4

2 回答 2

15

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

我创建了两个 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 是输家约 400 毫秒。解析需要 2452 毫秒,而“伪”变体需要 2033 毫秒。我将这个测试运行了 3 次,结果相似。

截屏

Test2:调整窗口大小

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

“许多 DOM 元素”是赢家,渲染时间为 1136 毫秒,而“伪元素”则为 1463 毫秒。

在此处输入图像描述

测试3:回流

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

但这从来没有花费超过 4 毫秒的时间来执行……没有足够的时间来可靠地测量性能。

显然 50.000 个元素不足以导致该区域的任何显着放缓。

PS:考试选的不是很科学,只是我最先想到的

于 2018-02-22T23:50:43.540 回答
-4

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

我不知道伪元素的性能,但我担心您将性能置于一切之上。

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

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

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

我敢肯定还有更多。另一方面是某种性能提升,我相信这将是微不足道的。

于 2013-04-15T20:44:08.060 回答