mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-11 10:18:15 +09:00
LibWeb: Add per-layer rule caches in StyleComputer
This allows us to filter by layer *once* instead of doing it for every rule that runs. Knocks ~2 seconds of loading time off of https://wpt.fyi/
This commit is contained in:
parent
e65ca3a7d2
commit
3b3f06ca68
Notes:
github-actions[bot]
2025-01-24 16:55:50 +00:00
Author: https://github.com/awesomekling
Commit: 3b3f06ca68
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3356
2 changed files with 35 additions and 37 deletions
|
@ -381,15 +381,17 @@ void StyleComputer::for_each_stylesheet(CascadeOrigin cascade_origin, Callback c
|
|||
}
|
||||
}
|
||||
|
||||
StyleComputer::RuleCache const& StyleComputer::rule_cache_for_cascade_origin(CascadeOrigin cascade_origin) const
|
||||
StyleComputer::RuleCache const* StyleComputer::rule_cache_for_cascade_origin(CascadeOrigin cascade_origin, FlyString const& qualified_layer_name) const
|
||||
{
|
||||
switch (cascade_origin) {
|
||||
case CascadeOrigin::Author:
|
||||
return *m_author_rule_cache;
|
||||
if (qualified_layer_name.is_empty())
|
||||
return m_author_rule_cache;
|
||||
return m_layer_rule_caches.get(qualified_layer_name).value_or(nullptr);
|
||||
case CascadeOrigin::User:
|
||||
return *m_user_rule_cache;
|
||||
return m_user_rule_cache;
|
||||
case CascadeOrigin::UserAgent:
|
||||
return *m_user_agent_rule_cache;
|
||||
return m_user_agent_rule_cache;
|
||||
default:
|
||||
TODO();
|
||||
}
|
||||
|
@ -405,13 +407,6 @@ StyleComputer::RuleCache const& StyleComputer::rule_cache_for_cascade_origin(Cas
|
|||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] static bool filter_layer(FlyString const& qualified_layer_name, MatchingRule const& rule)
|
||||
{
|
||||
if (rule.rule && rule.qualified_layer_name() != qualified_layer_name)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StyleComputer::should_reject_with_ancestor_filter(Selector const& selector) const
|
||||
{
|
||||
for (u32 hash : selector.ancestor_hashes()) {
|
||||
|
@ -483,19 +478,22 @@ Vector<MatchingRule> StyleComputer::collect_matching_rules(DOM::Element const& e
|
|||
else if (shadow_root)
|
||||
shadow_host = shadow_root->host();
|
||||
|
||||
auto const& rule_cache = rule_cache_for_cascade_origin(cascade_origin);
|
||||
auto const* maybe_rule_cache = rule_cache_for_cascade_origin(cascade_origin, qualified_layer_name);
|
||||
if (!maybe_rule_cache)
|
||||
return {};
|
||||
auto& rule_cache = *maybe_rule_cache;
|
||||
|
||||
Vector<MatchingRule, 512> rules_to_run;
|
||||
auto add_rules_to_run = [&](Vector<MatchingRule> const& rules) {
|
||||
rules_to_run.grow_capacity(rules_to_run.size() + rules.size());
|
||||
if (pseudo_element.has_value()) {
|
||||
for (auto const& rule : rules) {
|
||||
if (rule.contains_pseudo_element && filter_namespace_rule(element, rule) && filter_layer(qualified_layer_name, rule))
|
||||
if (rule.contains_pseudo_element && filter_namespace_rule(element, rule))
|
||||
rules_to_run.unchecked_append(rule);
|
||||
}
|
||||
} else {
|
||||
for (auto const& rule : rules) {
|
||||
if (!rule.contains_pseudo_element && filter_namespace_rule(element, rule) && filter_layer(qualified_layer_name, rule))
|
||||
if (!rule.contains_pseudo_element && filter_namespace_rule(element, rule))
|
||||
rules_to_run.unchecked_append(rule);
|
||||
}
|
||||
}
|
||||
|
@ -2463,8 +2461,7 @@ GC::Ref<ComputedProperties> StyleComputer::compute_properties(DOM::Element& elem
|
|||
if (pseudo_element.has_value())
|
||||
effect->set_pseudo_element(Selector::PseudoElement { pseudo_element.value() });
|
||||
|
||||
auto const& rule_cache = rule_cache_for_cascade_origin(CascadeOrigin::Author);
|
||||
if (auto keyframe_set = rule_cache.rules_by_animation_keyframes.get(animation->id()); keyframe_set.has_value())
|
||||
if (auto keyframe_set = m_author_rule_cache->rules_by_animation_keyframes.get(animation->id()); keyframe_set.has_value())
|
||||
effect->set_key_frame_set(keyframe_set.value());
|
||||
|
||||
effect->set_target(&element);
|
||||
|
@ -2593,9 +2590,12 @@ void StyleComputer::collect_selector_insights(Selector const& selector, Selector
|
|||
}
|
||||
}
|
||||
|
||||
NonnullOwnPtr<StyleComputer::RuleCache> StyleComputer::make_rule_cache_for_cascade_origin(CascadeOrigin cascade_origin, SelectorInsights& insights, Vector<MatchingRule>& hover_rules)
|
||||
StyleComputer::BuiltRuleCaches StyleComputer::make_rule_cache_for_cascade_origin(CascadeOrigin cascade_origin, SelectorInsights& insights, Vector<MatchingRule>& hover_rules)
|
||||
{
|
||||
auto rule_cache = make<RuleCache>();
|
||||
auto caches = BuiltRuleCaches {
|
||||
.main_rules = make<RuleCache>(),
|
||||
.layer_rules = {},
|
||||
};
|
||||
|
||||
size_t num_class_rules = 0;
|
||||
size_t num_id_rules = 0;
|
||||
|
@ -2638,6 +2638,9 @@ NonnullOwnPtr<StyleComputer::RuleCache> StyleComputer::make_rule_cache_for_casca
|
|||
false,
|
||||
};
|
||||
|
||||
auto const& qualified_layer_name = matching_rule.qualified_layer_name();
|
||||
auto& rule_cache = qualified_layer_name.is_empty() ? caches.main_rules : caches.layer_rules.ensure(qualified_layer_name, [] { return make<RuleCache>(); });
|
||||
|
||||
bool contains_root_pseudo_class = false;
|
||||
Optional<CSS::Selector::PseudoElement::Type> pseudo_element;
|
||||
|
||||
|
@ -2796,24 +2799,12 @@ NonnullOwnPtr<StyleComputer::RuleCache> StyleComputer::make_rule_cache_for_casca
|
|||
dbgln(" - keyframe {}: {} properties", it.key(), it->properties.size());
|
||||
}
|
||||
|
||||
rule_cache->rules_by_animation_keyframes.set(rule.name(), move(keyframe_set));
|
||||
caches.main_rules->rules_by_animation_keyframes.set(rule.name(), move(keyframe_set));
|
||||
});
|
||||
++style_sheet_index;
|
||||
});
|
||||
|
||||
size_t total_rules = num_class_rules + num_id_rules + num_tag_name_rules + num_pseudo_element_rules + num_root_rules + num_attribute_rules + rule_cache->other_rules.size();
|
||||
if constexpr (LIBWEB_CSS_DEBUG) {
|
||||
dbgln("Built rule cache!");
|
||||
dbgln(" ID: {}", num_id_rules);
|
||||
dbgln(" Class: {}", num_class_rules);
|
||||
dbgln(" TagName: {}", num_tag_name_rules);
|
||||
dbgln("PseudoElement: {}", num_pseudo_element_rules);
|
||||
dbgln(" Root: {}", num_root_rules);
|
||||
dbgln(" Attribute: {}", num_attribute_rules);
|
||||
dbgln(" Other: {}", rule_cache->other_rules.size());
|
||||
dbgln(" Total: {}", total_rules);
|
||||
}
|
||||
return rule_cache;
|
||||
return caches;
|
||||
}
|
||||
|
||||
struct LayerNode {
|
||||
|
@ -2897,9 +2888,11 @@ void StyleComputer::build_rule_cache()
|
|||
|
||||
build_qualified_layer_names_cache();
|
||||
|
||||
m_author_rule_cache = make_rule_cache_for_cascade_origin(CascadeOrigin::Author, *m_selector_insights, m_hover_rules);
|
||||
m_user_rule_cache = make_rule_cache_for_cascade_origin(CascadeOrigin::User, *m_selector_insights, m_hover_rules);
|
||||
m_user_agent_rule_cache = make_rule_cache_for_cascade_origin(CascadeOrigin::UserAgent, *m_selector_insights, m_hover_rules);
|
||||
auto author_rules = make_rule_cache_for_cascade_origin(CascadeOrigin::Author, *m_selector_insights, m_hover_rules);
|
||||
m_author_rule_cache = move(author_rules.main_rules);
|
||||
m_layer_rule_caches = move(author_rules.layer_rules);
|
||||
m_user_rule_cache = make_rule_cache_for_cascade_origin(CascadeOrigin::User, *m_selector_insights, m_hover_rules).main_rules;
|
||||
m_user_agent_rule_cache = make_rule_cache_for_cascade_origin(CascadeOrigin::UserAgent, *m_selector_insights, m_hover_rules).main_rules;
|
||||
}
|
||||
|
||||
void StyleComputer::invalidate_rule_cache()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue