1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 05:37:43 +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

@ -85,26 +85,30 @@ WebIDL::ExceptionOr<void> MutationObserver::observe(Node& target, MutationObserv
// 7. For each registered of targets registered observer list, if registereds observer is this:
bool updated_existing_observer = false;
for (auto& registered_observer : target.registered_observers_list()) {
if (registered_observer->observer().ptr() != this)
continue;
updated_existing_observer = true;
// 1. For each node of thiss node list, remove all transient registered observers whose source is registered from nodes registered observer list.
for (auto& node : m_node_list) {
// FIXME: Is this correct?
if (node.is_null())
if (target.registered_observer_list()) {
for (auto& registered_observer : *target.registered_observer_list()) {
if (registered_observer->observer().ptr() != this)
continue;
node->registered_observers_list().remove_all_matching([&registered_observer](RegisteredObserver& observer) {
return is<TransientRegisteredObserver>(observer) && verify_cast<TransientRegisteredObserver>(observer).source().ptr() == registered_observer;
});
}
updated_existing_observer = true;
// 2. Set registereds options to options.
registered_observer->set_options(options);
break;
// 1. For each node of thiss node list, remove all transient registered observers whose source is registered from nodes registered observer list.
for (auto& node : m_node_list) {
// FIXME: Is this correct?
if (node.is_null())
continue;
if (node->registered_observer_list()) {
node->registered_observer_list()->remove_all_matching([&registered_observer](RegisteredObserver& observer) {
return is<TransientRegisteredObserver>(observer) && verify_cast<TransientRegisteredObserver>(observer).source().ptr() == registered_observer;
});
}
}
// 2. Set registereds options to options.
registered_observer->set_options(options);
break;
}
}
// 8. Otherwise:
@ -129,9 +133,11 @@ void MutationObserver::disconnect()
if (node.is_null())
continue;
node->registered_observers_list().remove_all_matching([this](RegisteredObserver& registered_observer) {
return registered_observer.observer().ptr() == this;
});
if (node->registered_observer_list()) {
node->registered_observer_list()->remove_all_matching([this](RegisteredObserver& registered_observer) {
return registered_observer.observer().ptr() == this;
});
}
}
// 2. Empty thiss record queue.