From 6fc59039c41f5d7db5a0c5a5f8efb9e23f3940e1 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Tue, 19 Mar 2024 10:18:49 +0100 Subject: [PATCH] LibWeb: Skip cells layout in table box width calculation There is no need to run full table layout if we are only interested in calculating its width. This change reduces compute_table_box_width_inside_table_wrapper() from ~30% to ~15% in profiles of "File changed" pages on github. --- .../Libraries/LibWeb/Layout/FormattingContext.cpp | 15 ++++++++++----- .../LibWeb/Layout/TableFormattingContext.cpp | 13 ++++++++++--- .../LibWeb/Layout/TableFormattingContext.h | 4 +++- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp index da1a95e1dbf..efba48cadfa 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -405,11 +405,6 @@ CSSPixels FormattingContext::compute_table_box_width_inside_table_wrapper(Box co // table-wrapper can't have borders or paddings but it might have margin taken from table-root. auto available_width = width_of_containing_block - margin_left.to_px(box) - margin_right.to_px(box); - LayoutState throwaway_state(&m_state); - auto context = create_independent_formatting_context_if_needed(throwaway_state, box); - VERIFY(context); - context->run(box, LayoutMode::IntrinsicSizing, m_state.get(box).available_inner_space_or_constraints_from(available_space)); - Optional table_box; box.for_each_in_subtree_of_type([&](Box const& child_box) { if (child_box.display().is_table_inside()) { @@ -420,6 +415,16 @@ CSSPixels FormattingContext::compute_table_box_width_inside_table_wrapper(Box co }); VERIFY(table_box.has_value()); + LayoutState throwaway_state(&m_state); + + auto& table_box_state = throwaway_state.get_mutable(*table_box); + auto const& table_box_computed_values = table_box->computed_values(); + table_box_state.border_left = table_box_computed_values.border_left().width; + table_box_state.border_right = table_box_computed_values.border_right().width; + + auto context = make(throwaway_state, *table_box, this); + context->run_until_width_calculation(*table_box, m_state.get(*table_box).available_inner_space_or_constraints_from(available_space)); + auto table_used_width = throwaway_state.get(*table_box).border_box_width(); return available_space.width.is_definite() ? min(table_used_width, available_width) : table_used_width; } diff --git a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp index 1fb51ac6493..a11070c57dc 100644 --- a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp @@ -1577,12 +1577,10 @@ void TableFormattingContext::finish_grid_initialization(TableGrid const& table_g } } -void TableFormattingContext::run(Box const& box, LayoutMode layout_mode, AvailableSpace const& available_space) +void TableFormattingContext::run_until_width_calculation(Box const& box, AvailableSpace const& available_space) { m_available_space = available_space; - auto total_captions_height = run_caption_layout(layout_mode, CSS::CaptionSide::Top); - // Determine the number of rows/columns the table requires. finish_grid_initialization(TableGrid::calculate_row_column_grid(box, m_cells, m_rows)); @@ -1603,6 +1601,15 @@ void TableFormattingContext::run(Box const& box, LayoutMode layout_mode, Availab // Compute the width of the table. compute_table_width(); +} + +void TableFormattingContext::run(Box const& box, LayoutMode layout_mode, AvailableSpace const& available_space) +{ + m_available_space = available_space; + + auto total_captions_height = run_caption_layout(layout_mode, CSS::CaptionSide::Top); + + run_until_width_calculation(box, available_space); if (available_space.width.is_intrinsic_sizing_constraint() && !available_space.height.is_intrinsic_sizing_constraint()) { return; diff --git a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.h b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.h index 7c4c04584bc..69c8443aeb3 100644 --- a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.h @@ -23,6 +23,8 @@ public: explicit TableFormattingContext(LayoutState&, Box const&, FormattingContext* parent); ~TableFormattingContext(); + void run_until_width_calculation(Box const&, AvailableSpace const& available_space); + virtual void run(Box const&, LayoutMode, AvailableSpace const&) override; virtual CSSPixels automatic_content_width() const override; virtual CSSPixels automatic_content_height() const override; @@ -146,7 +148,7 @@ private: static TableFormattingContext::ConflictingEdge const& winning_conflicting_edge(TableFormattingContext::ConflictingEdge const& a, TableFormattingContext::ConflictingEdge const& b); static const CSS::BorderData& border_data_conflicting_edge(ConflictingEdge const& conflicting_edge); - static const Painting::PaintableBox::BorderDataWithElementKind border_data_with_element_kind_from_conflicting_edge(ConflictingEdge const& conflicting_edge); + static Painting::PaintableBox::BorderDataWithElementKind const border_data_with_element_kind_from_conflicting_edge(ConflictingEdge const& conflicting_edge); class BorderConflictFinder { public: