将 &-nesting与 :has伪类结合使用会导致性能瓶颈
想象下面这个CSS规则,我在样式表中使用过:
.toplevel .small-container svg:has(> g[opacity="0.3"]) {
> g[opacity="0.3"],
+ .sibling-el {
opacity: .6 !important;
}
}
当使用上述规则时,动态内容的性能会完全崩溃。虽然来自 :has 的性能损耗总是难以避免,但这甚至会在DOM中没有带有 .small-container-class的元素时发生。似乎仍在对 :has() 进行评估,尽管评估本应在未找到 .small-container 时结束。
把它改写为
.toplevel {
.small-container svg:has(> g[opacity="0.3"]) + .sibling-el,
.small-container svg > g[opacity="0.3"] {
opacity: .6 !important;
}
}
就能完全解决性能问题。
我很好奇这是为什么……你认为这是浏览器的问题吗?浏览器没有正确地组合选择器?还是我对 &-nesting的工作方式还有误解?
解决方案
首先,这些选择器产生了以下结果:
/* 1st */
.toplevel .small-container svg:has(> g[opacity="0.3"]) > g[opacity="0.3"],
.toplevel .small-container svg:has(> g[opacity="0.3"]) + .sibling-el { }
/* 2nd */
.toplevel .small-container svg:has(> g[opacity="0.3"]) + .sibling-el,
.toplevel .small-container svg > g[opacity="0.3"] { }
在这里,“结果”是指浏览器实际计算出的内容。
接下来我们看到这一段:
...evaluation should have ended, when no
.small-containerwas found.
如果从左到右读取,这当然成立。问题在于,CSS的评估是从右到左进行的。
也许你把 .small-container 的名字改了以防止匹配,但引擎先查找 g[...] 或 .sibling-el,然后是 svg:has(...),再是那个 :has 的内容,最后在未找到 .small-container 时中止。
这是一个bug吗?
我认为不是,尤其是因为这些实际上是两个不同的、非等价的选择器。
关于性能,这里应该会有改进,因为 has 仍然是一个新特性。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。