From d65bebd8cf854453e430f1f6d35a1ad51f90f130 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 7 Dec 2020 19:56:53 +0100 Subject: [PATCH] LibWeb: Cache parsed inline style of DOM elements Instead of invoking the CSS parser every time we compute the style for an element that has a "style" attribute, we now cache the result of parsing the inline style whenever the "style" attribute is set. This is a nice boost to relayout performance since we no longer hit the CSS parser at all. --- Libraries/LibWeb/CSS/StyleResolver.cpp | 9 +++------ Libraries/LibWeb/DOM/Element.cpp | 5 ++++- Libraries/LibWeb/DOM/Element.h | 4 ++++ Libraries/LibWeb/Forward.h | 1 + 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Libraries/LibWeb/CSS/StyleResolver.cpp b/Libraries/LibWeb/CSS/StyleResolver.cpp index accc16032f..eee46797d3 100644 --- a/Libraries/LibWeb/CSS/StyleResolver.cpp +++ b/Libraries/LibWeb/CSS/StyleResolver.cpp @@ -567,12 +567,9 @@ NonnullRefPtr StyleResolver::resolve_style(const DOM::Element& } } - auto style_attribute = element.attribute(HTML::AttributeNames::style); - if (!style_attribute.is_null()) { - if (auto declaration = parse_css_declaration(CSS::ParsingContext(document()), style_attribute)) { - for (auto& property : declaration->properties()) { - set_property_expanding_shorthands(style, property.property_id, property.value, m_document); - } + if (auto* inline_style = element.inline_style()) { + for (auto& property : inline_style->properties()) { + set_property_expanding_shorthands(style, property.property_id, property.value, m_document); } } diff --git a/Libraries/LibWeb/DOM/Element.cpp b/Libraries/LibWeb/DOM/Element.cpp index 0ff0371be7..fd3776adda 100644 --- a/Libraries/LibWeb/DOM/Element.cpp +++ b/Libraries/LibWeb/DOM/Element.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -153,13 +154,15 @@ RefPtr Element::create_layout_node(const CSS::StyleProperties* par void Element::parse_attribute(const FlyString& name, const String& value) { - if (name == "class") { + if (name == HTML::AttributeNames::class_) { auto new_classes = value.split_view(' '); m_classes.clear(); m_classes.ensure_capacity(new_classes.size()); for (auto& new_class : new_classes) { m_classes.unchecked_append(new_class); } + } else if (name == HTML::AttributeNames::style) { + m_inline_style = parse_css_declaration(CSS::ParsingContext(document()), value); } } diff --git a/Libraries/LibWeb/DOM/Element.h b/Libraries/LibWeb/DOM/Element.h index b47eafdfa3..a52ad47e1f 100644 --- a/Libraries/LibWeb/DOM/Element.h +++ b/Libraries/LibWeb/DOM/Element.h @@ -90,6 +90,8 @@ public: const CSS::StyleProperties* resolved_style() const { return m_resolved_style.ptr(); } NonnullRefPtr computed_style(); + const CSS::StyleDeclaration* inline_style() const { return m_inline_style; } + // FIXME: innerHTML also appears on shadow roots. https://w3c.github.io/DOM-Parsing/#dom-innerhtml String inner_html() const; void set_inner_html(StringView); @@ -107,6 +109,8 @@ private: QualifiedName m_qualified_name; Vector m_attributes; + RefPtr m_inline_style; + RefPtr m_resolved_style; Vector m_classes; diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h index 9f8a5bff6e..35ff04a815 100644 --- a/Libraries/LibWeb/Forward.h +++ b/Libraries/LibWeb/Forward.h @@ -28,6 +28,7 @@ namespace Web::CSS { class Selector; +class StyleDeclaration; class StyleProperties; class StyleResolver; class StyleRule;