Skip to content

Commit e2a9a7f

Browse files
awesomeklingnico
authored andcommitted
LibWeb: Bucket CSS rules by pseudo-element
Instead of throwing all pseudo-element rules in one bucket, let's have one bucket per pseudo-element. This means we only run ::before rules for ::before pseudo-elements, only ::after rules for ::after, etc. Average style update time on https://tailwindcss.com/ 250ms -> 215ms. (cherry picked from commit 87056ee)
1 parent aeca8c4 commit e2a9a7f

File tree

2 files changed

+9
-3
lines changed

2 files changed

+9
-3
lines changed

Userland/Libraries/LibWeb/CSS/StyleComputer.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ Vector<MatchingRule> StyleComputer::collect_matching_rules(DOM::Element const& e
373373
if (auto it = rule_cache.rules_by_tag_name.find(element.local_name()); it != rule_cache.rules_by_tag_name.end())
374374
add_rules_to_run(it->value);
375375
if (pseudo_element.has_value())
376-
add_rules_to_run(rule_cache.pseudo_element_rules);
376+
add_rules_to_run(rule_cache.rules_by_pseudo_element[to_underlying(pseudo_element.value())]);
377377
if (element.is_document_element())
378378
add_rules_to_run(rule_cache.root_rules);
379379

@@ -2644,11 +2644,13 @@ NonnullOwnPtr<StyleComputer::RuleCache> StyleComputer::make_rule_cache_for_casca
26442644
};
26452645

26462646
bool contains_root_pseudo_class = false;
2647+
Optional<CSS::Selector::PseudoElement::Type> pseudo_element;
26472648

26482649
for (auto const& simple_selector : selector.compound_selectors().last().simple_selectors) {
26492650
if (!matching_rule.contains_pseudo_element) {
26502651
if (simple_selector.type == CSS::Selector::SimpleSelector::Type::PseudoElement) {
26512652
matching_rule.contains_pseudo_element = true;
2653+
pseudo_element = simple_selector.pseudo_element().type();
26522654
++num_pseudo_element_rules;
26532655
}
26542656
}
@@ -2735,7 +2737,11 @@ NonnullOwnPtr<StyleComputer::RuleCache> StyleComputer::make_rule_cache_for_casca
27352737
}
27362738
if (!added_to_bucket) {
27372739
if (matching_rule.contains_pseudo_element) {
2738-
rule_cache->pseudo_element_rules.append(move(matching_rule));
2740+
if (to_underlying(pseudo_element.value()) < to_underlying(CSS::Selector::PseudoElement::Type::KnownPseudoElementCount)) {
2741+
rule_cache->rules_by_pseudo_element[to_underlying(pseudo_element.value())].append(move(matching_rule));
2742+
} else {
2743+
// NOTE: We don't cache rules for unknown pseudo-elements. They can't match anything anyway.
2744+
}
27392745
} else if (contains_root_pseudo_class) {
27402746
rule_cache->root_rules.append(move(matching_rule));
27412747
} else {

Userland/Libraries/LibWeb/CSS/StyleComputer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ class StyleComputer {
213213
HashMap<FlyString, Vector<MatchingRule>> rules_by_class;
214214
HashMap<FlyString, Vector<MatchingRule>> rules_by_tag_name;
215215
HashMap<FlyString, Vector<MatchingRule>, AK::ASCIICaseInsensitiveFlyStringTraits> rules_by_attribute_name;
216-
Vector<MatchingRule> pseudo_element_rules;
216+
Array<Vector<MatchingRule>, to_underlying(CSS::Selector::PseudoElement::Type::KnownPseudoElementCount)> rules_by_pseudo_element;
217217
Vector<MatchingRule> root_rules;
218218
Vector<MatchingRule> other_rules;
219219

0 commit comments

Comments
 (0)