LibWeb: Cache the first <base href> (in tree order) in Document

When parsing relative URLs, we have to check the first <base href> in
tree order (if one is available). This was getting *very* costly on
large DOMs with many relative urls.

This patch avoids all that repeated traversal by letting Document cache
the first <base href> and invalidating the cache whenever a <base>
element is added/removed/edited in the DOM.

The browser was stuck doing this for a *very* long time when loading
the ECMA-262 spec, and this removes that problem entirely.
This commit is contained in:
Andreas Kling 2022-11-04 20:56:30 +01:00
parent 0aca69853c
commit b400a34984
Notes: sideshowbarker 2024-07-17 04:47:17 +09:00
4 changed files with 23 additions and 3 deletions

View file

@ -21,6 +21,8 @@ void HTMLBaseElement::inserted()
{
HTMLElement::inserted();
document().update_base_element({});
// The frozen base URL must be immediately set for an element whenever any of the following situations occur:
// - The base element becomes the first base element in tree order with an href content attribute in its Document.
@ -30,6 +32,12 @@ void HTMLBaseElement::inserted()
set_the_frozen_base_url();
}
void HTMLBaseElement::removed_from(Node* parent)
{
HTMLElement::removed_from(parent);
document().update_base_element({});
}
void HTMLBaseElement::parse_attribute(FlyString const& name, String const& value)
{
HTMLElement::parse_attribute(name, value);
@ -39,6 +47,8 @@ void HTMLBaseElement::parse_attribute(FlyString const& name, String const& value
if (name != AttributeNames::href)
return;
document().update_base_element({});
auto first_base_element_with_href_in_document = document().first_base_element_with_href_in_tree_order();
if (first_base_element_with_href_in_document.ptr() == this)
set_the_frozen_base_url();