由于我们在 HTML5 中有新元素(HEADER、FOOTER、SECTION...),我们应该如何构建我们的 CSS 选择器以提高性能?
header {}
header nav {}
header nav ul li{}
或者
#header {}
#header .nav{}
#header .nav .menu{}
或者以其他更有效的方式?
由于我们在 HTML5 中有新元素(HEADER、FOOTER、SECTION...),我们应该如何构建我们的 CSS 选择器以提高性能?
header {}
header nav {}
header nav ul li{}
或者
#header {}
#header .nav{}
#header .nav .menu{}
或者以其他更有效的方式?
如果“效率”是指它如何影响页面的加载时间,那么您应该坚持使用类和 ID 而不是标签名称。谷歌有一个编写快速 CSS的最佳实践页面,您可能会觉得有趣。他们建议的要点是减少浏览器必须排序的元素数量。
再次,页面上最相关的一点是“优先选择类和 ID 选择器而不是标签选择器”。正如我们稍后将看到的那样,只有当这些类和 ID 选择器减少匹配元素的数量时,这才真正提高了效率。
不过,在我开始之前,让我们从该页面的建议总和得出其合乎逻辑的结论。我们应该发现编写 CSS 最有效的方法是为页面上的所有内容应用 ID,并且只使用 ID 选择器。但是你应该这样做吗?可能不是。
原因是在编写 CSS 时还需要考虑其他因素。这里有几个:
semantic
,这绝对不意味着给你页面上的所有东西一个 ID。我从所有这些中得出的结论是,只要您不牺牲太多上述几点,尤其是第一点和第二点,就可以遵循效率的最佳实践。
对于您的具体示例,最简单的答案是底部选择器如果减少匹配项的数量会更有效。
一个一个地浏览它们:
header
对比#header
如果您的页面上有多个标题元素,ID 将始终更有效。如果只有一个标题,那么它们应该同样快速。
header nav
对比#header .nav
Google 最佳实践页面告诉我们,后代选择器是 CSS 中效率最低的选择器。
这是因为 CSS 从右到左读取。一旦它找到最右边的后代,它需要通过 DOM 树返回以确定其父代是否匹配。它必须在每场比赛中都这样做。
碰巧选择器在匹配失败时会停止解释。因此,如果它正在寻找 nav 并在 ul 上运行,它就不会在 DOM 树上寻找该 ul 的标题父级。这不应该让我们太惊讶,但我只是想为了完整起见我会提到它。
这些点共同使我们得出结论,在使用后代选择器时,您希望选择器的最右边部分尽可能具体。这最大化了不匹配的元素数量,从而最小化了慢速 DOM 树搜索的数量。
所以回到你的例子中的两个选择器:如果你有多个标题,其中有多个导航,但只有少数几个有 class .nav
,那么正确的效率会更高。如果您只有一个 ID 为 header 的 header 和一个 ID 为 nav 的 nav,那么它们将同样快速。
header nav ul li
对比#header .nav .menu
与之前相同的规则适用于本案。然而,在这种情况下,由于这里有两个后代选择器,而不仅仅是一个,这一事实放大了速度上的差异。
如果您的页面有多个无序列表,那么您可能希望使用这两个选择器中的第二个,以防止li
页面上的每个选择器匹配这个(更)复杂的选择器。
这取决于它们将如何被使用。如果它们只需要设置一次样式,则使用 header {} 否则添加类和/或 ID。