From 9b8464f455963a45f5c6cab8777c22cb1cf97268 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 23 Jun 2020 23:15:23 +0200 Subject: [PATCH] LibWeb: Cache the used CSS 'position' value on LayoutNodeWithStyle This avoids having to query the StyleProperties hash map whenever we need to know if an element is absolutely positioned. This was extremely hot in interactive window resize profiles. --- Libraries/LibWeb/Layout/LayoutBlock.cpp | 2 +- Libraries/LibWeb/Layout/LayoutBox.cpp | 2 +- Libraries/LibWeb/Layout/LayoutNode.cpp | 17 +++++++++++++---- Libraries/LibWeb/Layout/LayoutNode.h | 18 ++++++++++++------ 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/Libraries/LibWeb/Layout/LayoutBlock.cpp b/Libraries/LibWeb/Layout/LayoutBlock.cpp index 591142e2012..8f11b6b3fae 100644 --- a/Libraries/LibWeb/Layout/LayoutBlock.cpp +++ b/Libraries/LibWeb/Layout/LayoutBlock.cpp @@ -642,7 +642,7 @@ void LayoutBlock::place_block_level_non_replaced_element_in_normal_flow(LayoutBl auto* relevant_sibling = block.previous_sibling(); while (relevant_sibling != nullptr) { - if (relevant_sibling->style().position() != CSS::Position::Absolute) + if (relevant_sibling->position() != CSS::Position::Absolute) break; relevant_sibling = relevant_sibling->previous_sibling(); } diff --git a/Libraries/LibWeb/Layout/LayoutBox.cpp b/Libraries/LibWeb/Layout/LayoutBox.cpp index 4a1301c150e..3e679bbe44e 100644 --- a/Libraries/LibWeb/Layout/LayoutBox.cpp +++ b/Libraries/LibWeb/Layout/LayoutBox.cpp @@ -323,7 +323,7 @@ bool LayoutBox::establishes_stacking_context() const return false; if (node() == document().root()) return true; - auto position = style().position(); + auto position = this->position(); auto z_index = style().z_index(); if (position == CSS::Position::Absolute || position == CSS::Position::Relative) { if (z_index.has_value()) diff --git a/Libraries/LibWeb/Layout/LayoutNode.cpp b/Libraries/LibWeb/Layout/LayoutNode.cpp index a852ce2cb25..fd7d24f7d29 100644 --- a/Libraries/LibWeb/Layout/LayoutNode.cpp +++ b/Libraries/LibWeb/Layout/LayoutNode.cpp @@ -57,7 +57,7 @@ void LayoutNode::layout(LayoutMode layout_mode) bool LayoutNode::can_contain_boxes_with_position_absolute() const { - return style().position() != CSS::Position::Static || is_root(); + return position() != CSS::Position::Static || is_root(); } const LayoutBlock* LayoutNode::containing_block() const @@ -72,7 +72,7 @@ const LayoutBlock* LayoutNode::containing_block() const if (is_text()) return nearest_block_ancestor(); - auto position = style().position(); + auto position = this->position(); if (position == CSS::Position::Absolute) { auto* ancestor = parent(); @@ -199,7 +199,7 @@ bool LayoutNode::is_absolutely_positioned() const { if (!has_style()) return false; - auto position = style().position(); + auto position = this->position(); return position == CSS::Position::Absolute || position == CSS::Position::Fixed; } @@ -207,7 +207,16 @@ bool LayoutNode::is_fixed_position() const { if (!has_style()) return false; - return style().position() == CSS::Position::Fixed; + auto position = this->position(); + return position == CSS::Position::Fixed; +} + +LayoutNodeWithStyle::LayoutNodeWithStyle(const Node* node, NonnullRefPtr style) + : LayoutNode(node) + , m_style(move(style)) +{ + m_has_style = true; + m_position = m_style->position(); } } diff --git a/Libraries/LibWeb/Layout/LayoutNode.h b/Libraries/LibWeb/Layout/LayoutNode.h index df2c032a369..fa0b2a7882f 100644 --- a/Libraries/LibWeb/Layout/LayoutNode.h +++ b/Libraries/LibWeb/Layout/LayoutNode.h @@ -190,6 +190,7 @@ public: virtual LayoutNode& inline_wrapper() { return *this; } const StyleProperties& style() const; + CSS::Position position() const; LayoutNodeWithStyle* parent(); const LayoutNodeWithStyle* parent() const; @@ -257,16 +258,14 @@ public: const StyleProperties& style() const { return m_style; } void set_style(const StyleProperties& style) { m_style = style; } + CSS::Position position() const { return m_position; } + protected: - explicit LayoutNodeWithStyle(const Node* node, NonnullRefPtr style) - : LayoutNode(node) - , m_style(move(style)) - { - m_has_style = true; - } + explicit LayoutNodeWithStyle(const Node*, NonnullRefPtr); private: NonnullRefPtr m_style; + CSS::Position m_position; }; class LayoutNodeWithStyleAndBoxModelMetrics : public LayoutNodeWithStyle { @@ -291,6 +290,13 @@ inline const StyleProperties& LayoutNode::style() const return parent()->style(); } +inline CSS::Position LayoutNode::position() const +{ + if (m_has_style) + return static_cast(this)->position(); + return parent()->position(); +} + inline const LayoutNodeWithStyle* LayoutNode::parent() const { return static_cast(TreeNode::parent());