1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 04:27:44 +00:00

LibWeb: Cache CSS::Selector's pseudo element at construction time

Computing the pseudo element of a CSS::Selector was very hot when
mousing around on GitHub in Browser. A profile had it at ~10%.
After these changes, it's totally gone from the profile. :^)
This commit is contained in:
Andreas Kling 2022-03-13 16:28:20 +01:00
parent f5c2e87965
commit f88d65d9cb
2 changed files with 12 additions and 14 deletions

View file

@ -13,25 +13,22 @@ namespace Web::CSS {
Selector::Selector(Vector<CompoundSelector>&& compound_selectors) Selector::Selector(Vector<CompoundSelector>&& compound_selectors)
: m_compound_selectors(move(compound_selectors)) : m_compound_selectors(move(compound_selectors))
{ {
// Note: This assumes that only one pseudo-element is allowed in a selector, and that it appears at the end.
// This is true currently, and there are no current proposals to change this, but you never know!
if (!m_compound_selectors.is_empty()) {
for (auto const& simple_selector : m_compound_selectors.last().simple_selectors) {
if (simple_selector.type == SimpleSelector::Type::PseudoElement) {
m_pseudo_element = simple_selector.pseudo_element;
break;
}
}
}
} }
Selector::~Selector() Selector::~Selector()
{ {
} }
Optional<Selector::PseudoElement> Selector::pseudo_element() const
{
// Note: This assumes that only one pseudo-element is allowed in a selector, and that it appears at the end.
// This is true currently, and there are no current proposals to change this, but you never know!
if (compound_selectors().is_empty())
return {};
for (auto const& simple_selector : compound_selectors().last().simple_selectors) {
if (simple_selector.type == SimpleSelector::Type::PseudoElement)
return simple_selector.pseudo_element;
}
return {};
}
// https://www.w3.org/TR/selectors-4/#specificity-rules // https://www.w3.org/TR/selectors-4/#specificity-rules
u32 Selector::specificity() const u32 Selector::specificity() const
{ {

View file

@ -135,7 +135,7 @@ public:
~Selector(); ~Selector();
Vector<CompoundSelector> const& compound_selectors() const { return m_compound_selectors; } Vector<CompoundSelector> const& compound_selectors() const { return m_compound_selectors; }
Optional<PseudoElement> pseudo_element() const; Optional<PseudoElement> pseudo_element() const { return m_pseudo_element; }
u32 specificity() const; u32 specificity() const;
String serialize() const; String serialize() const;
@ -144,6 +144,7 @@ private:
Vector<CompoundSelector> m_compound_selectors; Vector<CompoundSelector> m_compound_selectors;
mutable Optional<u32> m_specificity; mutable Optional<u32> m_specificity;
Optional<Selector::PseudoElement> m_pseudo_element;
}; };
constexpr StringView pseudo_element_name(Selector::PseudoElement pseudo_element) constexpr StringView pseudo_element_name(Selector::PseudoElement pseudo_element)