From f61df9d34cbd6f5a2eb801f94d164b17e196887a Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 9 May 2025 15:35:59 +0200 Subject: [PATCH] LibWeb: Don't throw away UA shadow trees willy-nilly We were unnecessarily discarding the shadow trees of various elements when they were removed or detached from the DOM. This especially caused a *lot* of churn when creating input elements via setting .innerHTML on something. We ended up building each input element's shadow tree 3 times instead of 1. The original issue that we were trying to solve by discarding shadow trees appears to have been solved elsewhere, and nothing else seems to break by just allowing them to remain in place. 1.05x speedup on Speedometer's TodoMVC-jQuery. --- Libraries/LibWeb/HTML/HTMLDetailsElement.cpp | 6 ------ Libraries/LibWeb/HTML/HTMLDetailsElement.h | 1 - Libraries/LibWeb/HTML/HTMLInputElement.cpp | 5 ----- Libraries/LibWeb/HTML/HTMLInputElement.h | 1 - Libraries/LibWeb/HTML/HTMLMeterElement.cpp | 6 ------ Libraries/LibWeb/HTML/HTMLMeterElement.h | 1 - Libraries/LibWeb/HTML/HTMLProgressElement.cpp | 6 ------ Libraries/LibWeb/HTML/HTMLProgressElement.h | 1 - Libraries/LibWeb/HTML/HTMLSelectElement.cpp | 5 ----- Libraries/LibWeb/HTML/HTMLSelectElement.h | 1 - Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp | 5 ----- Libraries/LibWeb/HTML/HTMLTextAreaElement.h | 1 - 12 files changed, 39 deletions(-) diff --git a/Libraries/LibWeb/HTML/HTMLDetailsElement.cpp b/Libraries/LibWeb/HTML/HTMLDetailsElement.cpp index ab9d0078d56..46c32a4b682 100644 --- a/Libraries/LibWeb/HTML/HTMLDetailsElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLDetailsElement.cpp @@ -54,12 +54,6 @@ void HTMLDetailsElement::inserted() update_shadow_tree_slots(); } -void HTMLDetailsElement::removed_from(DOM::Node* old_parent, DOM::Node& old_root) -{ - Base::removed_from(old_parent, old_root); - set_shadow_root(nullptr); -} - // https://html.spec.whatwg.org/multipage/interactive-elements.html#the-details-element:concept-element-attributes-change-ext void HTMLDetailsElement::attribute_changed(FlyString const& local_name, Optional const& old_value, Optional const& value, Optional const& namespace_) { diff --git a/Libraries/LibWeb/HTML/HTMLDetailsElement.h b/Libraries/LibWeb/HTML/HTMLDetailsElement.h index 0e9ad921f5d..d6238f530bd 100644 --- a/Libraries/LibWeb/HTML/HTMLDetailsElement.h +++ b/Libraries/LibWeb/HTML/HTMLDetailsElement.h @@ -32,7 +32,6 @@ private: virtual void visit_edges(Cell::Visitor&) override; virtual void inserted() override; - virtual void removed_from(DOM::Node* old_parent, DOM::Node& old_root) override; virtual void children_changed(ChildrenChangedMetadata const*) override; virtual void attribute_changed(FlyString const& local_name, Optional const& old_value, Optional const& value, Optional const& namespace_) override; diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp index a49acfd7aaf..48359ac59d2 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -1793,11 +1793,6 @@ void HTMLInputElement::form_associated_element_was_inserted() } } -void HTMLInputElement::form_associated_element_was_removed(DOM::Node*) -{ - set_shadow_root(nullptr); -} - bool HTMLInputElement::is_presentational_hint(FlyString const& name) const { if (Base::is_presentational_hint(name)) diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.h b/Libraries/LibWeb/HTML/HTMLInputElement.h index 8f2d7e1d37a..017c442ee85 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.h +++ b/Libraries/LibWeb/HTML/HTMLInputElement.h @@ -192,7 +192,6 @@ public: virtual void clear_algorithm() override; virtual void form_associated_element_was_inserted() override; - virtual void form_associated_element_was_removed(DOM::Node*) override; virtual void form_associated_element_attribute_changed(FlyString const&, Optional const&, Optional const&) override; virtual WebIDL::ExceptionOr cloned(Node&, bool) const override; diff --git a/Libraries/LibWeb/HTML/HTMLMeterElement.cpp b/Libraries/LibWeb/HTML/HTMLMeterElement.cpp index 36d9ba403aa..cb3fc125550 100644 --- a/Libraries/LibWeb/HTML/HTMLMeterElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLMeterElement.cpp @@ -175,12 +175,6 @@ void HTMLMeterElement::inserted() create_shadow_tree_if_needed(); } -void HTMLMeterElement::removed_from(DOM::Node* old_parent, DOM::Node& old_root) -{ - Base::removed_from(old_parent, old_root); - set_shadow_root(nullptr); -} - void HTMLMeterElement::adjust_computed_style(CSS::ComputedProperties& style) { // https://drafts.csswg.org/css-display-3/#unbox diff --git a/Libraries/LibWeb/HTML/HTMLMeterElement.h b/Libraries/LibWeb/HTML/HTMLMeterElement.h index 7dd2f8aaadb..3f58caf67d2 100644 --- a/Libraries/LibWeb/HTML/HTMLMeterElement.h +++ b/Libraries/LibWeb/HTML/HTMLMeterElement.h @@ -35,7 +35,6 @@ public: // ^HTMLElement virtual void inserted() override; - virtual void removed_from(DOM::Node* old_parent, DOM::Node& old_root) override; virtual void adjust_computed_style(CSS::ComputedProperties&) override; diff --git a/Libraries/LibWeb/HTML/HTMLProgressElement.cpp b/Libraries/LibWeb/HTML/HTMLProgressElement.cpp index 9cad19badab..310649dc518 100644 --- a/Libraries/LibWeb/HTML/HTMLProgressElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLProgressElement.cpp @@ -96,12 +96,6 @@ void HTMLProgressElement::inserted() create_shadow_tree_if_needed(); } -void HTMLProgressElement::removed_from(DOM::Node* old_parent, DOM::Node& old_root) -{ - Base::removed_from(old_parent, old_root); - set_shadow_root(nullptr); -} - void HTMLProgressElement::adjust_computed_style(CSS::ComputedProperties& style) { // https://drafts.csswg.org/css-display-3/#unbox diff --git a/Libraries/LibWeb/HTML/HTMLProgressElement.h b/Libraries/LibWeb/HTML/HTMLProgressElement.h index e92527e417b..d3d0ee25337 100644 --- a/Libraries/LibWeb/HTML/HTMLProgressElement.h +++ b/Libraries/LibWeb/HTML/HTMLProgressElement.h @@ -29,7 +29,6 @@ public: // ^HTMLElement virtual void inserted() override; - virtual void removed_from(DOM::Node* old_parent, DOM::Node& old_root) override; virtual void adjust_computed_style(CSS::ComputedProperties&) override; diff --git a/Libraries/LibWeb/HTML/HTMLSelectElement.cpp b/Libraries/LibWeb/HTML/HTMLSelectElement.cpp index b3f751d304c..e32b3536f13 100644 --- a/Libraries/LibWeb/HTML/HTMLSelectElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLSelectElement.cpp @@ -574,11 +574,6 @@ void HTMLSelectElement::form_associated_element_was_inserted() create_shadow_tree_if_needed(); } -void HTMLSelectElement::form_associated_element_was_removed(DOM::Node*) -{ - set_shadow_root(nullptr); -} - void HTMLSelectElement::computed_properties_changed() { // Hide chevron icon when appearance is none diff --git a/Libraries/LibWeb/HTML/HTMLSelectElement.h b/Libraries/LibWeb/HTML/HTMLSelectElement.h index 134c2ff289b..dede0996a6f 100644 --- a/Libraries/LibWeb/HTML/HTMLSelectElement.h +++ b/Libraries/LibWeb/HTML/HTMLSelectElement.h @@ -97,7 +97,6 @@ public: virtual void activation_behavior(DOM::Event const&) override; virtual void form_associated_element_was_inserted() override; - virtual void form_associated_element_was_removed(DOM::Node*) override; void did_select_item(Optional const& id); diff --git a/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp b/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp index 4b0df8f316a..f079a07b474 100644 --- a/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp @@ -154,11 +154,6 @@ void HTMLTextAreaElement::form_associated_element_was_inserted() create_shadow_tree_if_needed(); } -void HTMLTextAreaElement::form_associated_element_was_removed(DOM::Node*) -{ - set_shadow_root(nullptr); -} - // https://html.spec.whatwg.org/multipage/form-elements.html#dom-textarea-defaultvalue String HTMLTextAreaElement::default_value() const { diff --git a/Libraries/LibWeb/HTML/HTMLTextAreaElement.h b/Libraries/LibWeb/HTML/HTMLTextAreaElement.h index f05e58fbc17..55258ceb4e4 100644 --- a/Libraries/LibWeb/HTML/HTMLTextAreaElement.h +++ b/Libraries/LibWeb/HTML/HTMLTextAreaElement.h @@ -70,7 +70,6 @@ public: virtual WebIDL::ExceptionOr cloned(Node&, bool) const override; virtual void form_associated_element_was_inserted() override; - virtual void form_associated_element_was_removed(DOM::Node*) override; virtual void form_associated_element_attribute_changed(FlyString const&, Optional const&, Optional const&) override; virtual void children_changed(ChildrenChangedMetadata const*) override;