Skip to content

Commit d1f34ef

Browse files
kalenikaliaksandrgmta
authored andcommitted
LibWeb: Avoid whole DOM traversal in document_tree_child_navigables()
Instead, iterate through all registered navigables and pick the ones that belong to document's tree, preserving tree order.
1 parent 4c22c37 commit d1f34ef

File tree

1 file changed

+11
-8
lines changed

1 file changed

+11
-8
lines changed

Libraries/LibWeb/DOM/Document.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4026,14 +4026,17 @@ Vector<GC::Root<HTML::Navigable>> Document::document_tree_child_navigables()
40264026

40274027
// 3. Let navigableContainers be a list of all descendants of document that are navigable containers, in tree order.
40284028
// 4. For each navigableContainer of navigableContainers:
4029-
for_each_in_subtree_of_type<HTML::NavigableContainer>([&](HTML::NavigableContainer& navigable_container) {
4030-
// 1. If navigableContainer's content navigable is null, then continue.
4031-
if (!navigable_container.content_navigable())
4032-
return TraversalDecision::Continue;
4033-
// 2. Append navigableContainer's content navigable to navigables.
4034-
navigables.append(*navigable_container.content_navigable());
4035-
return TraversalDecision::Continue;
4036-
});
4029+
// 1. If navigableContainer's content navigable is null, then continue.
4030+
// 2. Append navigableContainer's content navigable to navigables.
4031+
// OPTIMIZATION: Iterate all registered navigables to avoid a full tree traversal.
4032+
for (auto const& navigable : HTML::all_navigables()) {
4033+
auto container = navigable->container();
4034+
if (!container || !is_ancestor_of(*container))
4035+
continue;
4036+
navigables.insert_before_matching(*navigable, [&](auto const& existing_navigable) {
4037+
return container->is_before(*existing_navigable->container());
4038+
});
4039+
}
40374040

40384041
// 5. Return navigables.
40394042
return navigables;

0 commit comments

Comments
 (0)