Pārlūkot izejas kodu

LibWeb: Improve performance of CSS custom property resolution

By memoizing already resolved custom properties in the DOM::Element,
we achieve a notable speed increase when loading SerenityOS on GitHub.
Tobias Christiansen 4 gadi atpakaļ
vecāks
revīzija
301eb998c6

+ 7 - 3
Userland/Libraries/LibWeb/CSS/StyleResolver.cpp

@@ -765,8 +765,11 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope
     style.set_property(property_id, value);
 }
 
-StyleResolver::CustomPropertyResolutionTuple StyleResolver::resolve_custom_property_with_specificity(const DOM::Element& element, const String& custom_property_name) const
+StyleResolver::CustomPropertyResolutionTuple StyleResolver::resolve_custom_property_with_specificity(DOM::Element& element, const String& custom_property_name) const
 {
+    if (auto maybe_property = element.resolve_custom_property(custom_property_name); maybe_property.has_value())
+        return maybe_property.value();
+
     auto parent_element = element.parent_element();
     CustomPropertyResolutionTuple parent_resolved {};
     if (parent_element)
@@ -782,6 +785,7 @@ StyleResolver::CustomPropertyResolutionTuple StyleResolver::resolve_custom_prope
 
         auto custom_property_style = match.rule->declaration().custom_property(custom_property_name);
         if (custom_property_style.has_value()) {
+            element.add_custom_property(custom_property_name, { custom_property_style.value(), match.specificity });
             return { custom_property_style.value(), match.specificity };
         }
     }
@@ -789,14 +793,14 @@ StyleResolver::CustomPropertyResolutionTuple StyleResolver::resolve_custom_prope
     return parent_resolved;
 }
 
-Optional<StyleProperty> StyleResolver::resolve_custom_property(const DOM::Element& element, const String& custom_property_name) const
+Optional<StyleProperty> StyleResolver::resolve_custom_property(DOM::Element& element, const String& custom_property_name) const
 {
     auto resolved_with_specificity = resolve_custom_property_with_specificity(element, custom_property_name);
 
     return resolved_with_specificity.style;
 }
 
-NonnullRefPtr<StyleProperties> StyleResolver::resolve_style(const DOM::Element& element) const
+NonnullRefPtr<StyleProperties> StyleResolver::resolve_style(DOM::Element& element) const
 {
     auto style = StyleProperties::create();
 

+ 3 - 3
Userland/Libraries/LibWeb/CSS/StyleResolver.h

@@ -30,7 +30,7 @@ public:
     DOM::Document& document() { return m_document; }
     const DOM::Document& document() const { return m_document; }
 
-    NonnullRefPtr<StyleProperties> resolve_style(const DOM::Element&) const;
+    NonnullRefPtr<StyleProperties> resolve_style(DOM::Element&) const;
 
     Vector<MatchingRule> collect_matching_rules(const DOM::Element&) const;
     void sort_matching_rules(Vector<MatchingRule>&) const;
@@ -38,8 +38,8 @@ public:
         Optional<StyleProperty> style {};
         u32 specificity { 0 };
     };
-    CustomPropertyResolutionTuple resolve_custom_property_with_specificity(const DOM::Element&, const String&) const;
-    Optional<StyleProperty> resolve_custom_property(const DOM::Element&, const String&) const;
+    CustomPropertyResolutionTuple resolve_custom_property_with_specificity(DOM::Element&, const String&) const;
+    Optional<StyleProperty> resolve_custom_property(DOM::Element&, const String&) const;
 
     static bool is_inherited_property(CSS::PropertyID);
 

+ 12 - 0
Userland/Libraries/LibWeb/DOM/Element.h

@@ -8,6 +8,8 @@
 
 #include <AK/FlyString.h>
 #include <AK/String.h>
+#include <LibWeb/CSS/CSSStyleDeclaration.h>
+#include <LibWeb/CSS/StyleResolver.h>
 #include <LibWeb/DOM/Attribute.h>
 #include <LibWeb/DOM/ExceptionOr.h>
 #include <LibWeb/DOM/NonDocumentTypeChildNode.h>
@@ -91,6 +93,15 @@ public:
     const ShadowRoot* shadow_root() const { return m_shadow_root; }
     void set_shadow_root(RefPtr<ShadowRoot>);
 
+    Optional<CSS::StyleResolver::CustomPropertyResolutionTuple> resolve_custom_property(const String& custom_property_name)
+    {
+        return m_custom_properties.get(custom_property_name);
+    }
+    void add_custom_property(const String& custom_property_name, CSS::StyleResolver::CustomPropertyResolutionTuple style_property)
+    {
+        m_custom_properties.set(custom_property_name, style_property);
+    }
+
 protected:
     RefPtr<Layout::Node> create_layout_node() override;
 
@@ -107,6 +118,7 @@ private:
     RefPtr<CSS::CSSStyleDeclaration> m_inline_style;
 
     RefPtr<CSS::StyleProperties> m_specified_css_values;
+    HashMap<String, CSS::StyleResolver::CustomPropertyResolutionTuple> m_custom_properties;
 
     Vector<FlyString> m_classes;