mirror of
https://github.com/fergalmoran/ladybird.git
synced 2025-12-25 02:40:49 +00:00
LibWeb: Make HTMLCollection faster when it only cares about children
Some of the live HTMLCollection only ever contain children of their root node. When we know that's the case, we can avoid doing a full subtree traversal of all descendants and only visit children. This cuts the ECMA262 spec loading time by over 10 seconds. :^)
This commit is contained in:
@@ -13,15 +13,16 @@
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<HTMLCollection>> HTMLCollection::create(ParentNode& root, Function<bool(Element const&)> filter)
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<HTMLCollection>> HTMLCollection::create(ParentNode& root, Scope scope, Function<bool(Element const&)> filter)
|
||||
{
|
||||
return MUST_OR_THROW_OOM(root.heap().allocate<HTMLCollection>(root.realm(), root, move(filter)));
|
||||
return MUST_OR_THROW_OOM(root.heap().allocate<HTMLCollection>(root.realm(), root, scope, move(filter)));
|
||||
}
|
||||
|
||||
HTMLCollection::HTMLCollection(ParentNode& root, Function<bool(Element const&)> filter)
|
||||
HTMLCollection::HTMLCollection(ParentNode& root, Scope scope, Function<bool(Element const&)> filter)
|
||||
: LegacyPlatformObject(root.realm())
|
||||
, m_root(root)
|
||||
, m_filter(move(filter))
|
||||
, m_scope(scope)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -44,11 +45,19 @@ void HTMLCollection::visit_edges(Cell::Visitor& visitor)
|
||||
JS::MarkedVector<Element*> HTMLCollection::collect_matching_elements() const
|
||||
{
|
||||
JS::MarkedVector<Element*> elements(m_root->heap());
|
||||
m_root->for_each_in_subtree_of_type<Element>([&](auto& element) {
|
||||
if (m_filter(element))
|
||||
elements.append(const_cast<Element*>(&element));
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
if (m_scope == Scope::Descendants) {
|
||||
m_root->for_each_in_subtree_of_type<Element>([&](auto& element) {
|
||||
if (m_filter(element))
|
||||
elements.append(const_cast<Element*>(&element));
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
} else {
|
||||
m_root->for_each_child_of_type<Element>([&](auto& element) {
|
||||
if (m_filter(element))
|
||||
elements.append(const_cast<Element*>(&element));
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user