-
Notifications
You must be signed in to change notification settings - Fork 22.8k
Description
Proposal
I recently learned from Firefox developers that certain forms of CSS :has()
selectors can have vastly different performance characteristics when I reported a Firefox bug.
They shared the following tips:
anchoring :has() to an element (or to all elements) slow all DOM mutations inside that subtree (more the more complex the selector inside :has() is). So stuff like body:has() or :root:has() or *:has() are just a recipe for bad performance
- :has(...) with an under-constrained compound may trigger many subtree-traversals: e.g. With :has(.foo), every DOM mutation will cause subtree traversals to see if that element does have .foo in the subtree.
- :has(...) with an under-constrained inner selector compound may trigger many ancestor-traversals: e.g. With .ancestor:has(.foo > *), any DOM mutation will cause ancestor traversals to see if there's a :has() anchor to be invalidated. i.e. We need to check if the mutated DOM element has a .foo parent, and if we do, need to check for .ancestor to restyle.
- Any occurrence of above can affect invalidation performance of otherwise well-constrained :has() selectors.
I would like to add this somewhere on MDN so these performance implications can become more widely known, but I wasn't sure where to put it.
Potential pages that occurred to me include:
I wasn't sure if the :has()
page itself was okay or not, as it might be required to match a very specific format like other CSS pages.
Browser support
No response
Tasks
- [ ]
Dependencies
- [ ]
Additional information
No response
Are you willing to support this work?
Yes, I can help write content once the contect place for it to live is decided.