14

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

+但是,如果“在样式表中的任何地方遇到任何同级选择器......这包括选择器和像:first-childand之类的选择器”,则整个页面的优化将完全关闭:last-child

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

--

更多信息

  • Tali Garsiel 关于浏览器内部的研究中讨论了优化:浏览器的工作原理

  • 这是Dave Hyatt对兄弟选择器的完整引用,他显然是浏览器代码的作者:“根本不能使用兄弟选择器。当遇到任何兄弟选择器时,WebCore 会简单地抛出一个全局开关,并禁用整个文档的样式共享当它们出现时。这包括 + 选择器和选择器,例如 :first-child 和 :last-child。"

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

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

  • Nate Koechley的这篇文章更详细地讨论了该算法。他总结道:

    “在 Web 开发中,通常有 6 种不同的相似方法来做同样的事情。优秀的 Web 开发人员不断选择几乎无法区分的最佳路径。凯悦的这些内幕技巧为我们提供了更完整的了解浏览器的本质,并将帮助我们选择最佳方法。”

  • 凯悦还讨论了此W3C 邮件列表存档中的优化

  • 它还在 Ryan Kinal 的Stack 聊天中简短地出现:“哇。哇。我再也不会使用另一个兄弟选择器了。”

我特别想知道:

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

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

  • 是否存在任何测试表明它对渲染性能有多大影响

4

2 回答 2

2

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

WebKit 对样式更新的处理

属性变化

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

状态变化

WebKit 中的状态变化没有统一的设置。对于在 Gecko 中通过布尔状态处理的每个伪类,选择器匹配都有一个专用函数,它可以调用该元素来测试该伪类是否匹配。对元素内部状态的更改负责直接将该元素标记为需要重新计算样式。同样,没有尝试优化后代上的选择器匹配或处理' + '或' ~'。这里有一些优化,类似于 Gecko 为:hover那个封面所做的优化:hover:active,还有一些关于拖动的优化。

处理插入和删除

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

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

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

资源

于 2013-08-23T13:50:12.367 回答
0

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

如果 css 具有内置的 web 颜色,那么根据 Selector 上的 w3 规范,任何类型的选择器都不会出现任何问题。

以下规则与上一个示例中的规则类似,不同之处在于它添加了一个类选择器。因此,仅当 H1 具有 class="opener" 时才会出现特殊格式:

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

所以规则是标准化的,但 webkit 浏览器中肯定存在一些错误,它在等待特定选择器时停止。

于 2013-08-28T11:16:14.013 回答