From cf9565551a9368d5730550128401cf38f31f79a3 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 3 Aug 2023 14:08:02 +0200 Subject: [PATCH] LibWeb: Don't filter CSS rules into separate list based on @namespace Instead, perform the filtering for each rule as we go. This avoids creating a separate list of rules, which was ~5% of runtime when mousing around on the Discord web interface. --- .../Libraries/LibWeb/CSS/StyleComputer.cpp | 33 ++++++++----------- Userland/Libraries/LibWeb/CSS/StyleComputer.h | 2 -- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp index 221c363a2d..0a16fd66bd 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -220,23 +220,14 @@ StyleComputer::RuleCache const& StyleComputer::rule_cache_for_cascade_origin(Cas } } -Vector StyleComputer::filter_namespace_rules(DOM::Element const& element, Vector const& rules) const +[[nodiscard]] static bool filter_namespace_rule(DOM::Element const& element, MatchingRule const& rule) { - Vector filtered_rules; - - for (auto const& rule : rules) { - auto namespace_uri = rule.sheet->default_namespace(); - if (namespace_uri.has_value()) { - if (namespace_uri.value() == element.namespace_uri()) - filtered_rules.append(rule); - } else { - filtered_rules.append(rule); - } - } - // FIXME: Filter out non-default namespace using prefixes - - return filtered_rules; + auto namespace_uri = rule.sheet->default_namespace(); + if (namespace_uri.has_value() && namespace_uri.value() != element.namespace_uri()) { + return false; + } + return true; } Vector StyleComputer::collect_matching_rules(DOM::Element const& element, CascadeOrigin cascade_origin, Optional pseudo_element) const @@ -245,15 +236,17 @@ Vector StyleComputer::collect_matching_rules(DOM::Element const& e Vector rules_to_run; auto add_rules_to_run = [&](Vector const& rules) { - Vector namespace_filtered_rules = filter_namespace_rules(element, rules); - + rules_to_run.grow_capacity(rules_to_run.size() + rules.size()); if (pseudo_element.has_value()) { - for (auto& rule : namespace_filtered_rules) { - if (rule.contains_pseudo_element) + for (auto const& rule : rules) { + if (rule.contains_pseudo_element && filter_namespace_rule(element, rule)) rules_to_run.append(rule); } } else { - rules_to_run.extend(namespace_filtered_rules); + for (auto const& rule : rules) { + if (filter_namespace_rule(element, rule)) + rules_to_run.append(rule); + } } }; diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.h b/Userland/Libraries/LibWeb/CSS/StyleComputer.h index 9079e2d5c8..10a3d4570b 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.h +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.h @@ -174,8 +174,6 @@ private: void build_rule_cache(); void build_rule_cache_if_needed() const; - Vector filter_namespace_rules(DOM::Element const&, Vector const&) const; - JS::NonnullGCPtr m_document; struct AnimationKeyFrameSet {