mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 19:17:41 +00:00
LibWeb: Limit style update tree traversal to dirty subtrees
This patch adds a second style dirty bit that tracks whether a DOM node has one or more children with dirty style. This allows the style update to skip over entire subtrees where all nodes are clean.
This commit is contained in:
parent
d1479aef56
commit
6809be436b
3 changed files with 32 additions and 7 deletions
|
@ -400,13 +400,25 @@ void Document::update_layout()
|
|||
}
|
||||
}
|
||||
|
||||
void Document::update_style()
|
||||
static void update_style_recursively(DOM::Node& node)
|
||||
{
|
||||
for_each_in_subtree_of_type<Element>([&](auto& element) {
|
||||
if (element.needs_style_update())
|
||||
element.recompute_style();
|
||||
node.for_each_child([&](auto& child) {
|
||||
if (child.needs_style_update()) {
|
||||
if (is<Element>(child))
|
||||
downcast<Element>(child).recompute_style();
|
||||
child.set_needs_style_update(false);
|
||||
}
|
||||
if (child.child_needs_style_update()) {
|
||||
update_style_recursively(child);
|
||||
child.set_child_needs_style_update(false);
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
}
|
||||
|
||||
void Document::update_style()
|
||||
{
|
||||
update_style_recursively(*this);
|
||||
update_layout();
|
||||
}
|
||||
|
||||
|
|
|
@ -254,8 +254,17 @@ void Node::set_needs_style_update(bool value)
|
|||
if (m_needs_style_update == value)
|
||||
return;
|
||||
m_needs_style_update = value;
|
||||
if (m_needs_style_update)
|
||||
|
||||
if (m_needs_style_update) {
|
||||
for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent())
|
||||
ancestor->m_child_needs_style_update = true;
|
||||
document().schedule_style_update();
|
||||
}
|
||||
}
|
||||
|
||||
void Node::inserted_into(Node&)
|
||||
{
|
||||
set_needs_style_update(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ public:
|
|||
Element* parent_element();
|
||||
const Element* parent_element() const;
|
||||
|
||||
virtual void inserted_into(Node&) { }
|
||||
virtual void inserted_into(Node&);
|
||||
virtual void removed_from(Node&) { }
|
||||
virtual void children_changed() { }
|
||||
|
||||
|
@ -140,6 +140,9 @@ public:
|
|||
bool needs_style_update() const { return m_needs_style_update; }
|
||||
void set_needs_style_update(bool);
|
||||
|
||||
bool child_needs_style_update() const { return m_child_needs_style_update; }
|
||||
void set_child_needs_style_update(bool b) { m_child_needs_style_update = b; }
|
||||
|
||||
void invalidate_style();
|
||||
|
||||
bool is_link() const;
|
||||
|
@ -157,7 +160,8 @@ protected:
|
|||
Document* m_document { nullptr };
|
||||
mutable WeakPtr<Layout::Node> m_layout_node;
|
||||
NodeType m_type { NodeType::INVALID };
|
||||
bool m_needs_style_update { true };
|
||||
bool m_needs_style_update { false };
|
||||
bool m_child_needs_style_update { false };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue