1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 11:57:35 +00:00

LibWeb: Only allocate DOM::Node registered observer list on demand

Most DOM nodes don't have registered mutation observers, so let's put
the metadata about them behind an OwnPtr to save space in the common
case.

Saves 16 bytes per DOM node that doesn't have registered observers.
This commit is contained in:
Andreas Kling 2023-11-18 11:22:51 +01:00
parent c1fd55ce94
commit 9edfd5e360
4 changed files with 53 additions and 32 deletions

View file

@ -103,8 +103,10 @@ void Node::visit_edges(Cell::Visitor& visitor)
visitor.visit(m_layout_node);
visitor.visit(m_paintable);
for (auto& registered_observer : m_registered_observer_list)
visitor.visit(registered_observer);
if (m_registered_observer_list) {
for (auto& registered_observer : *m_registered_observer_list)
visitor.visit(registered_observer);
}
}
// https://dom.spec.whatwg.org/#dom-node-baseuri
@ -686,10 +688,12 @@ void Node::remove(bool suppress_observers)
// if registereds options["subtree"] is true, then append a new transient registered observer
// whose observer is registereds observer, options is registereds options, and source is registered to nodes registered observer list.
for (auto* inclusive_ancestor = parent; inclusive_ancestor; inclusive_ancestor = inclusive_ancestor->parent()) {
for (auto& registered : inclusive_ancestor->m_registered_observer_list) {
if (!inclusive_ancestor->m_registered_observer_list)
continue;
for (auto& registered : *inclusive_ancestor->m_registered_observer_list) {
if (registered->options().subtree) {
auto transient_observer = TransientRegisteredObserver::create(registered->observer(), registered->options(), registered);
m_registered_observer_list.append(move(transient_observer));
m_registered_observer_list->append(move(transient_observer));
}
}
}
@ -1546,7 +1550,9 @@ void Node::queue_mutation_record(FlyString const& type, Optional<FlyString> cons
// 2. Let nodes be the inclusive ancestors of target.
// 3. For each node in nodes, and then for each registered of nodes registered observer list:
for (auto* node = this; node; node = node->parent()) {
for (auto& registered_observer : node->m_registered_observer_list) {
if (!node->m_registered_observer_list)
continue;
for (auto& registered_observer : *node->m_registered_observer_list) {
// 1. Let options be registereds options.
auto& options = registered_observer->options();
@ -1995,4 +2001,11 @@ ErrorOr<void> Node::prepend_with_space(StringBuilder x, StringView const& result
return {};
}
void Node::add_registered_observer(RegisteredObserver& registered_observer)
{
if (!m_registered_observer_list)
m_registered_observer_list = make<Vector<JS::NonnullGCPtr<RegisteredObserver>>>();
m_registered_observer_list->append(registered_observer);
}
}