6

鉴于 CSS 处理细节,最显着的是RTL 匹配选择器效率,应该如何纯粹从渲染引擎性能的角度编写选择器?

这应该涵盖一般方面,包括使用或避免使用伪类、伪元素和关系选择器。

4

1 回答 1

8

在运行时,HTML 文档被解析为包含N具有平均深度的元素的 DOM 树D。应用的样式表中还有一共有SCSS 规则。

  1. 元素的样式是单独应用的,这意味着它们与整体复杂性之间存在直接关系N。值得注意的是,这可能会被浏览器逻辑所抵消,例如引用缓存和来自相同元素的回收样式。例如,以下列表项将应用相同的 CSS 属性(假设没有:nth-child应用诸如此类的伪类):

    <ul class="sample">
      <li>one</li>
      <li>two</li>
      <li>three</li>
    </ul>
    
  2. 选择器从右到左匹配单个规则资格 - 即,如果最右边的键与特定元素不匹配,则无需进一步处理选择器并将其丢弃。这意味着最右边的键应该匹配尽可能少的元素。下面,描述符将匹配更多元素,包括目标容器之外p的段落(当然,不会应用该规则,但仍会导致对该特定选择器的资格检查进行更多迭代):

    .custom-container p {}
    .container .custom-paragraph {}
    
  3. 关系选择器:后代选择器最多D需要迭代的元素。例如,如果元素处于父子关系中,成功匹配可能只需要一个步骤,但在确认元素不匹配并安全丢弃规则之前,.container .content需要遍历 DOM 树。html这也适用于链式后代选择器,但有一些限制。

    另一方面,>子选择器、+相邻选择器或:first-child仍需要评估附加元素,但隐含深度仅为 1,并且永远不需要进一步的树遍历。

  4. 伪元素的行为定义:before:after暗示它们不是 RTL 范式的一部分。假设的逻辑是,在规则指示将其插入元素内容之前或之后之前,本身没有伪元素(这反过来需要额外的 DOM 操作,但不需要额外的计算来匹配选择器本身)。

  5. 我找不到任何关于伪类的信息,例如:nth-child()or :disabled。验证元素状态需要额外的计算,但从规则解析的角度来看,只有将它们排除在 RTL 处理之外才有意义。

考虑到这些关系,计算复杂性O(N*D*S)应该主要通过最小化 CSS 选择器的深度和解决上面的点 2 来降低。与单独减少 CSS 规则或 HTML 元素的数量相比,这将带来可量化的更强改进^

浅层的,最好是一级的,特定的选择器处理得更快。这被谷歌带到了一个全新的水平(以编程方式,而不是手动!),例如很少有三键选择器,搜索结果中的大多数规则看起来像

#gb {}
#gbz, #gbg {}
#gbz {}
#gbg {}
#gbs {}
.gbto #gbs {}
#gbx3, #gbx4 {}
#gbx3 {}
#gbx4 {}
/*...*/

^ - 虽然从渲染引擎性能的角度来看这是正确的,但总会有额外的因素,例如流量开销和 DOM 解析等。

来源:1 2 3 4 5

于 2012-06-27T02:42:48.753 回答