From e4621704ceb5dd81d70eeab50c277bc469da9b7d Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 2 Nov 2023 07:48:51 +0100 Subject: [PATCH] LibWeb: Avoid unnecessary JS::Handles in Node::queue_mutation_record() We don't need to make a list of the target node's ancestors before iterating over them, since nothing happens while iterating them that can disturb the list anyway (no arbitrary JS execution etc). The incessant construction and destruction of handles here was showing up in profiles of basically every website that uses JavaScript to build some or all of their DOM tree. --- Userland/Libraries/LibWeb/DOM/Node.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/Userland/Libraries/LibWeb/DOM/Node.cpp b/Userland/Libraries/LibWeb/DOM/Node.cpp index 2b775c197e..b619e749ca 100644 --- a/Userland/Libraries/LibWeb/DOM/Node.cpp +++ b/Userland/Libraries/LibWeb/DOM/Node.cpp @@ -1544,14 +1544,8 @@ void Node::queue_mutation_record(FlyString const& type, Optional> interested_observers; // 2. Let nodes be the inclusive ancestors of target. - Vector> nodes; - nodes.append(JS::make_handle(*this)); - - for (auto* parent_node = parent(); parent_node; parent_node = parent_node->parent()) - nodes.append(JS::make_handle(*parent_node)); - // 3. For each node in nodes, and then for each registered of node’s registered observer list: - for (auto& node : nodes) { + for (auto* node = this; node; node = node->parent()) { for (auto& registered_observer : node->m_registered_observer_list) { // 1. Let options be registered’s options. auto& options = registered_observer->options(); @@ -1563,7 +1557,7 @@ void Node::queue_mutation_record(FlyString const& type, Optionalcontains_slow(attribute_name.value_or("").view()))) && !(type == MutationType::characterData && (!options.character_data.has_value() || !options.character_data.value()))