From 83bb16ede3543771985afa3dab83c567257c2432 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 20 Jul 2022 18:13:11 +0200 Subject: [PATCH] LibWeb: Avoid some unnecessary inside layouts during intrinsic sizing When calculating intrinsic sizes, we don't need to recurse into *every* box and layout its insides. IIUC, we can skip any unconstrained box with definite sizes in both axes. So this patch does exactly that. --- .../Libraries/LibWeb/Layout/FormattingContext.cpp | 14 ++++++++++++++ .../LibWeb/Layout/InlineFormattingContext.cpp | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp index 4d37ac4f92..fb409452d4 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -146,6 +146,20 @@ OwnPtr FormattingContext::create_independent_formatting_conte OwnPtr FormattingContext::layout_inside(Box const& child_box, LayoutMode layout_mode) { + { + // OPTIMIZATION: If we're doing intrinsic sizing and `child_box` has definite size in both axes, + // we don't need to layout its insides. The size is resolvable without learning + // the metrics of whatever's inside the box. + auto const& used_values = m_state.get(child_box); + if (layout_mode == LayoutMode::IntrinsicSizing + && used_values.width_constraint == SizeConstraint::None + && used_values.height_constraint == SizeConstraint::None + && used_values.has_definite_width() + && used_values.has_definite_height()) { + return nullptr; + } + } + if (!child_box.can_have_children()) return {}; diff --git a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp index 6afd3fa672..d96e35a086 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp @@ -150,7 +150,8 @@ void InlineFormattingContext::dimension_box_on_line(Box const& box, LayoutMode l box_state.set_content_height(height_value.resolved(box, container_height).to_px(inline_block)); } - independent_formatting_context->parent_context_did_dimension_child_root_box(); + if (independent_formatting_context) + independent_formatting_context->parent_context_did_dimension_child_root_box(); return; }