From 73f1c7a0309834d628180ac3ac49bef0dd581db9 Mon Sep 17 00:00:00 2001 From: Sebastian Zaha Date: Wed, 12 Jul 2023 11:23:33 +0200 Subject: [PATCH] LibWeb: Remove many redundant SVGUseElement clone calls This prevents SVG elements referenced by "use" being repeatedly cloned in many redundant cases. Pages that use a large svg "sprite" that then is referenced many times with "use" elements would load extremely slowly, or crash the page. --- Userland/Libraries/LibWeb/SVG/SVGElement.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Userland/Libraries/LibWeb/SVG/SVGElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGElement.cpp index 3b982aea48..f3f64e114f 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGElement.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGElement.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -60,7 +61,18 @@ void SVGElement::children_changed() void SVGElement::update_use_elements_that_reference_this() { - if (is(this)) { + if (is(this) + // If this element is in a shadow root, it already represents a clone and is not itself referenced. + || is(this->root()) + // If this does not have an id it cannot be referenced, no point in searching the entire DOM tree. + || !this->has_attribute(HTML::AttributeNames::id) + // An unconnected node cannot have valid references. + // This also prevents searches for elements that are in the process of being constructed - as clones. + || !this->is_connected() + // Each use element already listens for the completely_loaded event and then clones its referece, + // we do not have to also clone it in the process of initial DOM building. + || !document().is_completely_loaded()) { + return; } @@ -79,7 +91,7 @@ void SVGElement::removed_from(Node* parent) void SVGElement::remove_from_use_element_that_reference_this() { - if (is(this)) { + if (is(this) || !this->has_attribute(HTML::AttributeNames::id)) { return; }