Skip to content

Commit

Permalink
LibWeb: Only invalidate style/layout on mutation for connected DOM nodes
Browse files Browse the repository at this point in the history
If a DOM node isn't connected, there's no need to invalidate, since it's
not going to be visible anyway. The node will be automatically inserted
if/when it becomes connected in the future.
  • Loading branch information
awesomekling committed Apr 15, 2024
1 parent 7c50dc4 commit 0a563f3
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 13 deletions.
27 changes: 17 additions & 10 deletions Userland/Libraries/LibWeb/DOM/Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,10 @@ void Node::set_text_content(Optional<String> const& maybe_content)

// Otherwise, do nothing.

document().invalidate_style();
document().invalidate_layout();
if (is_connected()) {
document().invalidate_style();
document().invalidate_layout();
}

document().bump_dom_tree_version();
}
Expand Down Expand Up @@ -510,10 +512,11 @@ void Node::insert_before(JS::NonnullGCPtr<Node> node, JS::GCPtr<Node> child, boo
// 9. Run the children changed steps for parent.
children_changed();

// FIXME: This will need to become smarter when we implement the :has() selector.
invalidate_style();

document().invalidate_layout();
if (is_connected()) {
// FIXME: This will need to become smarter when we implement the :has() selector.
invalidate_style();
document().invalidate_layout();
}

document().bump_dom_tree_version();
}
Expand Down Expand Up @@ -569,6 +572,8 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Node>> Node::append_child(JS::NonnullGCPtr<
// https://dom.spec.whatwg.org/#concept-node-remove
void Node::remove(bool suppress_observers)
{
bool was_connected = is_connected();

// 1. Let parent be node’s parent
auto* parent = this->parent();

Expand Down Expand Up @@ -705,10 +710,12 @@ void Node::remove(bool suppress_observers)
// 21. Run the children changed steps for parent.
parent->children_changed();

// Since the tree structure has changed, we need to invalidate both style and layout.
// In the future, we should find a way to only invalidate the parts that actually need it.
document().invalidate_style();
document().invalidate_layout();
if (was_connected) {
// Since the tree structure has changed, we need to invalidate both style and layout.
// In the future, we should find a way to only invalidate the parts that actually need it.
document().invalidate_style();
document().invalidate_layout();
}

document().bump_dom_tree_version();
}
Expand Down
7 changes: 4 additions & 3 deletions Userland/Libraries/LibWeb/DOMParsing/InnerHTML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@ WebIDL::ExceptionOr<void> inner_html_setter(JS::NonnullGCPtr<DOM::Node> context_
if (!is<HTML::HTMLTemplateElement>(*context_object)) {
context_object->set_needs_style_update(true);

// NOTE: Since the DOM has changed, we have to rebuild the layout tree.
context_object->document().invalidate_layout();
context_object->document().set_needs_layout();
if (context_object->is_connected()) {
// NOTE: Since the DOM has changed, we have to rebuild the layout tree.
context_object->document().invalidate_layout();
}
}

return {};
Expand Down

0 comments on commit 0a563f3

Please sign in to comment.