通用选择器对性能有何影响?
Posted
技术标签:
【中文标题】通用选择器对性能有何影响?【英文标题】:What is the performance impact of the universal selector? 【发布时间】:2011-02-26 11:26:33 【问题描述】:我试图在每月获得数百万次页面浏览量的页面中找到一些简单的客户端性能调整。我担心的一个问题是使用 CSS 通用选择器 (*
)。
例如,考虑一个非常简单的 html 文档,如下所示:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Example</title>
<style type="text/css">
*
margin: 0;
padding: 0;
</head>
<body>
<h1>This is a heading</h1>
<p>This is a paragraph of text.</p>
</body>
</html>
通用选择器会将上述声明应用于body
、h1
和p
元素,因为它们是文档中唯一的元素。
一般来说,我是否会从以下规则中看到更好的性能:
body, h1, p
margin: 0;
padding: 0;
或者这会产生完全相同的净效应吗?
通用选择器是否执行了我可能不知道的更多工作?
我意识到此示例中的性能影响可能非常小,但我希望学到一些东西,可能会在实际情况下带来更显着的性能改进。
我不打算用文档后面的其他样式覆盖通用选择器规则中的样式 - 即将其用作快速而肮脏的重置样式表。实际上,我正在尝试完全按照我的预期使用通用选择器 - 一劳永逸地将规则集应用于文档中的所有元素。
最终,我希望确定通用选择器是否存在固有的缓慢问题,或者它是否由于滥用泛滥而名声不佳。如果* margin: 0;
字面上等同于body, h1, p margin: 0;
,那么这将回答我的问题,我会知道使用前者,因为它更简洁。如果不是,我想了解为什么通用选择器执行得更慢。
【问题讨论】:
从性能的角度来看,什么时候最好全局禁用(或启用)everything 的特性,最终重新设置它?学习浏览器默认设置不会花费你很长时间——你可以从“重置”CSS 文件中获得提示,但我不会去实际使用一个。开源浏览器具有开源 CSS 默认值,您可以查看。 我不确定您是否理解我的问题。我不想在这里重置然后重新应用样式,而是将规则应用于页面上的每个元素。我的问题是使用通用选择器在技术上是否与单独选择每个元素相同,或者是否会因任何原因导致性能损失。*
并不等同于 body, h1, p
,原因很明显。它执行速度较慢的唯一 原因是因为您将样式应用于所有内容,而任何其他选择器将您限制为 DOM 中特定元素的子集。但真正的问题是,浏览器是否会因为应用太多样式而变得无响应?我对此表示高度怀疑。另见:* box-sizing: border-box FTW
【参考方案1】:
在现代浏览器中,性能影响可以忽略不计,前提是您不对每个元素都应用慢速效果(例如 box-shadow、z 轴旋转)。通用选择器很慢的神话是十年前很慢的遗留物。
参考:http://www.kendoui.com/blogs/teamblog/posts/12-09-28/css_tip_star_selector_not_that_bad.aspx
【讨论】:
没错,从几年前开始,但不是神话,那是当时的现实【参考方案2】:我了解通配符会对性能产生影响,但在较小的网站上影响可以忽略不计。通配符是基于渐进增强构建站点的非常有用的工具。显然,使用 HTML * 之类的东西确实会影响大型网站的性能,但使其更具体,例如 #element_id *,有助于快速对子元素进行通用更改.
毕竟,通配符的存在是有原因的。您只需要了解何时使用它会比不使用它更有益。这取决于上下文。
我在制作 CSS 模板时使用通配符和通用选择器。这也是使用自定义样式快速调整不熟悉的 WordPress 主题中的一系列元素的好方法。
即使是流行且精简的 Bootstrap,也在适当的情况下使用通配符。
参考文献:
http://getbootstrap.com/css/ Gustafson, A. 2015。自适应网页设计:通过渐进增强打造丰富体验。伯克利 (CA):新车手。【讨论】:
【参考方案3】:避免使用通用选择器总是会加快您的页面呈现速度。通配符 * 很慢,尤其是当您的页面变成复杂的嵌套并且您的元素数量猛增时。
您应该始终将 ID 指定到尽可能低的级别(我意识到这几乎是不可能的,尤其是在处理诸如数据库结果之类的事情时)。但是当你使用像
这样的选择器时.mysuperclass ul li p a
您有一个类,后跟四个通用选择器 - 这意味着对于 .mysuperclass 的每个元素,渲染引擎必须遍历该父级中的每个元素以查找这些规则。
简而言之,我的回答是尽可能具体地使用 CSS,并使用选择器尽可能深入到 DOM。避免使用通配符和泛型。
【讨论】:
谢谢,贾罗德。我想我可以在我的问题中更好地强调我确实想使用我的 CSS 规则来定位页面上的每个元素 - 即,据我所知,通用选择器正是我在这种情况下想要的。由于我也一直听说通用选择器很慢,我希望了解这种缓慢是选择器固有的,还是仅基于其典型用法(例如,将遵循的快速而肮脏的重置样式表通过样式覆盖)。 我明白了。我建议使用 Chrome 的开发者工具进行一些速度测试。对其进行测试并查看使用通配符选择器与显式标记定义的结果。 Chrome 会详细说明每个过程需要多长时间。 我会建议 反对 使用您的选择器“尽可能具体”。将来,当您想要更改样式或遇到更多异常时,您将希望覆盖这些选择器,它们越具体,就越难。保持低特异性,并使用更多的元素和类选择器。 numiko.com/labs/2011/07/css-specificity-wars 完全同意 chharvey 的观点,更高的特异性 = 更大的膨胀 + 更努力地维护和扩展。我的一般规则是永远不要使用超过 2 级的嵌套规则。即使在大型项目中,这也是绝对可以实现的,尤其是在使用像 BEM 这样的方法时 (getbem.com) 这是可怕的“建议”。当必须搜索每个嵌套元素时,它非常慢。你使用 .mysuperclass a 就可以了。以上是关于通用选择器对性能有何影响?的主要内容,如果未能解决你的问题,请参考以下文章
使用多个中间件对应用程序性能有何影响?或者多少中间件对应用程序性能有好处? [关闭]
在 Rails 3 应用程序中使用 require_dependency 对性能有何影响?
在 web2py 中使用“rows.render()”对性能有何影响?