渲染优化和兄弟选择器

时间:2013-08-21 01:36:03

标签: css performance webkit internals

WebKit浏览器具有内置的样式渲染优化技术,“甚至不必匹配页面上大约60%元素的样式。”

但是,如果在样式表中的任何地方遇到任何兄弟选择器,则完全关闭该优化...这包括+选择器和选择器,如:first-child和{{1 }}“。

有没有人知道禁用此优化的选择器类型的完整列表?

-

更多信息

  • Tali Garsiel关于浏览器内部的研究中讨论了优化:How Browsers Work

  • 以下是来自Dave Hyatt的兄弟选择器的完整引用,他们显然是在编写浏览器代码:“根本没有使用兄弟选择器。当任何兄弟选择器是时,WebCore只会抛出一个全局开关遇到并禁用整个文档存在时的样式共享。这包括+选择器和选择器,如:first-child和:last-child。“

  • 这句话似乎来自于2005年凯悦写的一篇文章。下面他将更详细地讨论它(与之前相同的来源):

    “WebCore(即将推出的Safari)我提出了一个非常酷的优化,以避免甚至不必计算适用于元素的声明集。这种优化实际上甚至不必匹配页面上大约60%的元素的样式优化背后的想法是通过DOM(和其他状态)检查识别页面中的两个元素何时具有相同的样式,并尽可能简单地在这两个元素之间共享前端样式信息。“

  • article by Nate Koechley更详细地讨论了算法。他总结说:“在Web开发中,通常有6种不同的类似方法来做同样的事情。一个优秀的Web开发人员不断选择几乎无法区分的最佳路径这些来自凯悦的内幕贴士让我们更全面地了解浏览器的内容,并帮助我们选择最佳方法。“

  • 凯悦还在此W3C mailing list archive

  • 中讨论了优化问题
  • 在Ryan Kinal的Stack chat中也简要介绍过:“哇。哇哇。我再也不会再使用另一个兄弟选择器了。”

我特别感兴趣知道:

  • 子选择器是否也会关闭优化

  • Trident / IE是否使用任何类似的优化

  • 是否存在任何测试表明它在渲染表现方面有多大差异

2 个答案:

答案 0 :(得分:2)

我没有完整的列表,但我认为来自mozilla和Servo的这篇文章可能会有所帮助。

WebKit处理样式更新

属性更改

如果该元素尚未标记样式recalc,并且该属性是id属性或者存在涉及该属性的选择器,则该元素将标记为样式recalc。没有尝试仔细检查这些选择器是否与元素有关,也没有尝试在此阶段处理涉及“~”和“+”的案例。当类属性发生变化时,还会有一个单独的挂钩,除其他外,无条件地将元素标记为需要样式重新计算。同样,没有尝试处理“~”和“+”。 在这些情况中都没有尝试优化远离后代的选择器匹配。

状态更改

WebKit中没有统一的状态更改设置。对于通过Gecko中的布尔状态处理的每个伪类,选择器匹配具有一个专用函数,它可以调用该元素来测试该伪类是否匹配。对元素内部状态的更改负责直接将该元素标记为需要样式recalc。 同样,没有尝试优化远离后代的选择器匹配或处理' + '或'~'。这里有一些优化类似于一个Gecko为:hover提供:hover:active,以及有关拖动的内容。

处理插入和删除

RenderStyle有标志,指示其孩子是否受到各种结构伪类和“+”或“~”组合子的影响。在DOM突变上,更改后的第一个受影响的元素(以子列表顺序)被标记为需要样式recalc,或者父项的单个第一个子元素(如果它可能需要重新计算)。如果更改之前的更多内容可能需要重新计算,那么父项被标记为需要样式重新计算,这将重新计算其所有孩子。 在所有这些情况下,当实际重新计算元素上的样式时,会检查其孩子是否受到“+”或“~”的影响。如果是这样,那么如果有任何孩子被标记为需要样式重新计算,那么后面的孩子或其后的所有孩子(取决于是否涉及'+'或'~')也被标记为需要风格recalc。我认为,围绕多个“+”链存在一些错误。

结果是,在某些情况下,据我所知,WebKit最终会重新计算比Gecko更多元素的样式,但在其他情况下,它最终会在更少的元素上重新计算样式。例如,给定一个像“.foo ~ span”这样的选择器和一个将类从“foo”更改为“bar”的div,Gecko将重新安排div的所有后来的兄弟,而WebKit根本不会做任何工作没有“跨度”的孩子,因为在这种情况下它永远不会标记父母受到' + '的影响。我不确定这会影响插入行为的程度,看起来两者应该更相似。 不知怎的在HTML5单页规范脚本上,WebKit似乎比Gecko做得更好,我现在无法弄清楚为什么。也许这仅仅是因为它的风格重新计算似乎比Gecko实际运行便宜得多。

另一个结果是,个人属性和状态变化所涉及的工作比Gecko要少得多,代价是更多的样式重新计算。 DOM插入/删除所涉及的工作大致相同。

source

答案 1 :(得分:0)

我没有看到选择器出现任何问题,直到选择器样式的图像很重,需要时间加载。

如果css是内置网页颜色,任何类型的选择器不应该遇到任何问题,根据选择器上的w3规范..

以下规则与前一个示例中的规则类似,只是它添加了一个类选择器。因此,只有当H1具有class =“opener”时才会出现特殊格式:

h1.opener + h2 { margin-top: -5mm }   

因此规则是标准化的,但webkit浏览器中必定存在一些错误,这会在等待特定选择器时停止。