根据计算复杂性选择有效的选择器

o.v*_*.v. 6 css performance css-selectors

鉴于CSS处理细节,最值得注意的是RTL匹配和选择器效率,如何从渲染引擎性能的角度纯粹编写选择器?

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

o.v*_*.v. 6

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

  1. 元素的风格是单独应用的,这意味着整体复杂性之间存在直接关系N.值得注意的是,这可以通过浏览器逻辑(例如参考缓存和来自相同元素的回收样式)进行一定程度的抵消.例如,以下列表项将应用相同的CSS属性(假设没有应用伪类:nth-child):

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

    .custom-container p {}
    .container .custom-paragraph {}
    
    Run Code Online (Sandbox Code Playgroud)
  3. 关系选择器:后代选择器需要D迭代最多元素.例如,.container .content如果元素处于父子关系中,成功匹配可能只需要一步,但是在html确认元素不匹配并且安全地丢弃规则之前,需要遍历DOM树.这适用于链式后代选择器,有一些余量.

    另一方面,>子选择器,+相邻选择器或:first-child仍需要评估其他元素,但只有一个隐含深度,并且永远不需要进一步的树遍历.

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

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

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

浅,优选一级特定选择器处理更快.谷歌(以编程方式,而不是手动)将其提升到一个全新的水平!例如,很少有三键选择器,搜索结果中的大多数规则看起来像

#gb {}
#gbz, #gbg {}
#gbz {}
#gbg {}
#gbs {}
.gbto #gbs {}
#gbx3, #gbx4 {}
#gbx3 {}
#gbx4 {}
/*...*/
Run Code Online (Sandbox Code Playgroud)

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

资料来源:1 2 3 4 5