mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-27 06:48:49 +00:00
LibWeb: Bucket hover rules using RuleCache
Analysis of selectors on modern websites shows that the `:hover` pseudo-class is mostly used in the subject position within relatively simple selectors like `.a:hover`. This suggests that we could greatly benefit from segregating them by id/class/tag name, this way reducing number of selectors tested during hover style invalidation. With this change, hover invalidation on Discord goes down from 70ms to 3ms on my machine. I also tested GMail and GitHub where this change shows nice 2x-3x speedup.
This commit is contained in:
parent
ff8826d582
commit
0ab61a94d7
Notes:
github-actions[bot]
2025-02-22 09:15:47 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: 0ab61a94d7
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3650
3 changed files with 28 additions and 23 deletions
|
@ -420,10 +420,10 @@ RuleCache const* StyleComputer::rule_cache_for_cascade_origin(CascadeOrigin casc
|
|||
return true;
|
||||
}
|
||||
|
||||
Vector<MatchingRule> const& StyleComputer::get_hover_rules() const
|
||||
RuleCache const& StyleComputer::get_hover_rules() const
|
||||
{
|
||||
build_rule_cache_if_needed();
|
||||
return m_hover_rules;
|
||||
return *m_hover_rule_cache;
|
||||
}
|
||||
|
||||
InvalidationSet StyleComputer::invalidation_set_for_properties(Vector<InvalidationSet::Property> const& properties) const
|
||||
|
@ -2637,7 +2637,7 @@ void StyleComputer::collect_selector_insights(Selector const& selector, Selector
|
|||
}
|
||||
}
|
||||
|
||||
void StyleComputer::make_rule_cache_for_cascade_origin(CascadeOrigin cascade_origin, SelectorInsights& insights, Vector<MatchingRule>& hover_rules)
|
||||
void StyleComputer::make_rule_cache_for_cascade_origin(CascadeOrigin cascade_origin, SelectorInsights& insights)
|
||||
{
|
||||
Vector<MatchingRule> matching_rules;
|
||||
size_t style_sheet_index = 0;
|
||||
|
@ -2734,9 +2734,9 @@ void StyleComputer::make_rule_cache_for_cascade_origin(CascadeOrigin cascade_ori
|
|||
}
|
||||
|
||||
if (selector.contains_hover_pseudo_class()) {
|
||||
hover_rules.append(matching_rule);
|
||||
// For hover rule cache we intentionally pass pseudo_element as None, because we don't want to bucket hover rules by pseudo element type
|
||||
m_hover_rule_cache->add_rule(matching_rule, {}, contains_root_pseudo_class);
|
||||
}
|
||||
|
||||
rule_cache.add_rule(matching_rule, pseudo_element, contains_root_pseudo_class);
|
||||
}
|
||||
++rule_index;
|
||||
|
@ -2864,9 +2864,10 @@ void StyleComputer::build_rule_cache()
|
|||
|
||||
build_qualified_layer_names_cache();
|
||||
|
||||
make_rule_cache_for_cascade_origin(CascadeOrigin::Author, *m_selector_insights, m_hover_rules);
|
||||
make_rule_cache_for_cascade_origin(CascadeOrigin::User, *m_selector_insights, m_hover_rules);
|
||||
make_rule_cache_for_cascade_origin(CascadeOrigin::UserAgent, *m_selector_insights, m_hover_rules);
|
||||
m_hover_rule_cache = make<RuleCache>();
|
||||
make_rule_cache_for_cascade_origin(CascadeOrigin::Author, *m_selector_insights);
|
||||
make_rule_cache_for_cascade_origin(CascadeOrigin::User, *m_selector_insights);
|
||||
make_rule_cache_for_cascade_origin(CascadeOrigin::UserAgent, *m_selector_insights);
|
||||
}
|
||||
|
||||
void StyleComputer::invalidate_rule_cache()
|
||||
|
@ -2883,7 +2884,7 @@ void StyleComputer::invalidate_rule_cache()
|
|||
// If we are sure that it's safe, we could keep it as an optimization.
|
||||
m_user_agent_rule_cache = nullptr;
|
||||
|
||||
m_hover_rules.clear_with_capacity();
|
||||
m_hover_rule_cache = nullptr;
|
||||
m_style_invalidation_data = nullptr;
|
||||
}
|
||||
|
||||
|
@ -3112,7 +3113,7 @@ void RuleCache::add_rule(MatchingRule const& matching_rule, Optional<Selector::P
|
|||
}
|
||||
}
|
||||
|
||||
if (matching_rule.contains_pseudo_element) {
|
||||
if (matching_rule.contains_pseudo_element && pseudo_element.has_value()) {
|
||||
if (Selector::PseudoElement::is_known_pseudo_element_type(pseudo_element.value())) {
|
||||
rules_by_pseudo_element[to_underlying(pseudo_element.value())].append(matching_rule);
|
||||
} else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue