diff options
author | Andreas Kling <kling@serenityos.org> | 2022-03-16 17:51:37 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-03-16 18:06:45 +0100 |
commit | 0e8b538e0afe13d9109721c8cec4a2ee5c8456bf (patch) | |
tree | 350982ae283cc61c5e44046b9f6b9763c0cb2321 /Userland/Libraries | |
parent | f1711a562a610bc6d3b9969a814ebe913842c4d4 (diff) | |
download | serenity-0e8b538e0afe13d9109721c8cec4a2ee5c8456bf.zip |
LibWeb: Invalidate less style when moving between hovered nodes
Instead of invalidating style for the entire document, we now locate the
nearest common ancestor between the old and new innermost hovered node,
and only invalidate that ancestor and its descendants.
This drastically reduces the amount of style update work when mousing
around on GitHub (and any other pages, really.) It's actually really
really snappy now. Very cool! :^)
Diffstat (limited to 'Userland/Libraries')
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/Document.cpp | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index 42c8397462..9bf17e9bbf 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -672,6 +672,26 @@ void Document::set_inspected_node(Node* node) m_inspected_node->layout_node()->set_needs_display(); } +static Node* find_common_ancestor(Node* a, Node* b) +{ + if (!a || !b) + return nullptr; + + if (a == b) + return a; + + HashTable<Node*> ancestors; + for (auto* node = a; node; node = node->parent_or_shadow_host()) + ancestors.set(node); + + for (auto* node = b; node; node = node->parent_or_shadow_host()) { + if (ancestors.contains(node)) + return node; + } + + return nullptr; +} + void Document::set_hovered_node(Node* node) { if (m_hovered_node == node) @@ -680,7 +700,10 @@ void Document::set_hovered_node(Node* node) RefPtr<Node> old_hovered_node = move(m_hovered_node); m_hovered_node = node; - invalidate_style(); + if (auto* common_ancestor = find_common_ancestor(old_hovered_node, m_hovered_node)) + common_ancestor->invalidate_style(); + else + invalidate_style(); } NonnullRefPtr<HTMLCollection> Document::get_elements_by_name(String const& name) |