From 1f5c49f40d0383ef1f91d6e4d838230f04dfb738 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 3 Sep 2024 17:48:43 +0200 Subject: [PATCH] LibWeb: Make CSS::is_inherited_property(PropertyID) go fast Instead of switching on the PropertyID and doing a boatload of comparisons, we reorder the PropertyID enum so that all inherited properties are in two contiguous ranges (one for shorthands, one for longhands). This replaces the switch statement with two simple range checks. Note that the property order change is observable via window.getComputedStyle(), but the order of those properties is implementation defined anyway. Removes a 1.5% item from the profile when loading https://hemnet.se/ --- .../LibWeb/GenerateCSSPropertyID.cpp | 103 +++++++++--------- .../css/getComputedStyle-print-all.txt | 88 +++++++-------- 2 files changed, 93 insertions(+), 98 deletions(-) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPropertyID.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPropertyID.cpp index 2deff8effad..9b6568c6e42 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPropertyID.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPropertyID.cpp @@ -136,46 +136,61 @@ enum class PropertyID { All, )~~~"); - Vector shorthand_property_ids; - Vector longhand_property_ids; + Vector inherited_shorthand_property_ids; + Vector inherited_longhand_property_ids; + Vector noninherited_shorthand_property_ids; + Vector noninherited_longhand_property_ids; properties.for_each_member([&](auto& name, auto& value) { VERIFY(value.is_object()); - if (value.as_object().has("longhands"sv)) - shorthand_property_ids.append(name); - else - longhand_property_ids.append(name); + bool inherited = value.as_object().get_bool("inherited"sv).value_or(false); + if (value.as_object().has("longhands"sv)) { + if (inherited) + inherited_shorthand_property_ids.append(name); + else + noninherited_shorthand_property_ids.append(name); + } else { + if (inherited) + inherited_longhand_property_ids.append(name); + else + noninherited_longhand_property_ids.append(name); + } }); - auto first_property_id = shorthand_property_ids.first(); - auto last_property_id = longhand_property_ids.last(); + // Section order: + // 1. inherited shorthand properties + // 2. noninherited shorthand properties + // 3. inherited longhand properties + // 4. noninherited longhand properties - for (auto& name : shorthand_property_ids) { - auto member_generator = generator.fork(); - member_generator.set("name:titlecase", title_casify(name)); + auto first_property_id = inherited_shorthand_property_ids.first(); + auto last_property_id = noninherited_longhand_property_ids.last(); - member_generator.append(R"~~~( - @name:titlecase@, + auto emit_properties = [&](auto& property_ids) { + for (auto& name : property_ids) { + auto member_generator = generator.fork(); + member_generator.set("name:titlecase", title_casify(name)); + member_generator.append(R"~~~( + @name:titlecase@, )~~~"); - } + } + }; - for (auto& name : longhand_property_ids) { - auto member_generator = generator.fork(); - member_generator.set("name:titlecase", title_casify(name)); - - member_generator.append(R"~~~( - @name:titlecase@, -)~~~"); - } + emit_properties(inherited_shorthand_property_ids); + emit_properties(noninherited_shorthand_property_ids); + emit_properties(inherited_longhand_property_ids); + emit_properties(noninherited_longhand_property_ids); generator.set("first_property_id", title_casify(first_property_id)); generator.set("last_property_id", title_casify(last_property_id)); - generator.set("first_shorthand_property_id", title_casify(shorthand_property_ids.first())); - generator.set("last_shorthand_property_id", title_casify(shorthand_property_ids.last())); + generator.set("first_longhand_property_id", title_casify(inherited_longhand_property_ids.first())); + generator.set("last_longhand_property_id", title_casify(noninherited_longhand_property_ids.last())); - generator.set("first_longhand_property_id", title_casify(longhand_property_ids.first())); - generator.set("last_longhand_property_id", title_casify(longhand_property_ids.last())); + generator.set("first_inherited_shorthand_property_id", title_casify(inherited_shorthand_property_ids.first())); + generator.set("last_inherited_shorthand_property_id", title_casify(inherited_shorthand_property_ids.last())); + generator.set("first_inherited_longhand_property_id", title_casify(inherited_longhand_property_ids.first())); + generator.set("last_inherited_longhand_property_id", title_casify(inherited_longhand_property_ids.last())); generator.append(R"~~~( }; @@ -247,8 +262,10 @@ bool property_affects_stacking_context(PropertyID); constexpr PropertyID first_property_id = PropertyID::@first_property_id@; constexpr PropertyID last_property_id = PropertyID::@last_property_id@; -constexpr PropertyID first_shorthand_property_id = PropertyID::@first_shorthand_property_id@; -constexpr PropertyID last_shorthand_property_id = PropertyID::@last_shorthand_property_id@; +constexpr PropertyID first_inherited_shorthand_property_id = PropertyID::@first_inherited_shorthand_property_id@; +constexpr PropertyID last_inherited_shorthand_property_id = PropertyID::@last_inherited_shorthand_property_id@; +constexpr PropertyID first_inherited_longhand_property_id = PropertyID::@first_inherited_longhand_property_id@; +constexpr PropertyID last_inherited_longhand_property_id = PropertyID::@last_inherited_longhand_property_id@; constexpr PropertyID first_longhand_property_id = PropertyID::@first_longhand_property_id@; constexpr PropertyID last_longhand_property_id = PropertyID::@last_longhand_property_id@; @@ -543,33 +560,11 @@ bool is_animatable_property(PropertyID property_id) bool is_inherited_property(PropertyID property_id) { - switch (property_id) { -)~~~"); - - properties.for_each_member([&](auto& name, auto& value) { - VERIFY(value.is_object()); - - bool inherited = false; - if (value.as_object().has("inherited"sv)) { - auto inherited_value = value.as_object().get_bool("inherited"sv); - VERIFY(inherited_value.has_value()); - inherited = inherited_value.value(); - } - - if (inherited) { - auto member_generator = generator.fork(); - member_generator.set("name:titlecase", title_casify(name)); - member_generator.append(R"~~~( - case PropertyID::@name:titlecase@: + if (property_id >= first_inherited_shorthand_property_id && property_id <= last_inherited_longhand_property_id) return true; -)~~~"); - } - }); - - generator.append(R"~~~( - default: - return false; - } + if (property_id >= first_inherited_longhand_property_id && property_id <= last_inherited_longhand_property_id) + return true; + return false; } bool property_affects_layout(PropertyID property_id) diff --git a/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt b/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt index 7e1523719d3..1f55c71a758 100644 --- a/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt +++ b/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt @@ -1,3 +1,46 @@ +-webkit-text-fill-color: rgb(0, 0, 0) +accent-color: auto +border-collapse: separate +border-spacing: 0px +caption-side: top +clip-rule: nonzero +color: rgb(0, 0, 0) +cursor: auto +direction: ltr +fill: rgb(0, 0, 0) +fill-opacity: 1 +fill-rule: nonzero +font-family: serif +font-size: 16px +font-stretch: normal +font-style: normal +font-variant: normal +font-weight: 400 +image-rendering: auto +letter-spacing: normal +line-height: normal +list-style-image: none +list-style-position: outside +list-style-type: disc +math-depth: 0 +math-shift: normal +math-style: normal +pointer-events: auto +quotes: auto +stroke: none +stroke-opacity: 1 +stroke-width: 1px +text-align: start +text-anchor: start +text-decoration-line: none +text-indent: 0px +text-justify: auto +text-shadow: none +text-transform: none +visibility: visible +white-space: normal +word-spacing: normal +word-wrap: normal -webkit-align-content: normal -webkit-align-items: normal -webkit-align-self: auto @@ -26,14 +69,12 @@ -webkit-justify-content: normal -webkit-mask: none -webkit-order: 0 --webkit-text-fill-color: rgb(0, 0, 0) -webkit-transform: none -webkit-transform-origin: 50% 50% -webkit-transition-delay: 0s -webkit-transition-duration: 0s -webkit-transition-property: all -webkit-transition-timing-function: ease -accent-color: auto align-content: normal align-items: normal align-self: auto @@ -62,14 +103,12 @@ border-bottom-left-radius: 0px border-bottom-right-radius: 0px border-bottom-style: none border-bottom-width: medium -border-collapse: separate border-left-color: rgb(0, 0, 0) border-left-style: none border-left-width: medium border-right-color: rgb(0, 0, 0) border-right-style: none border-right-width: medium -border-spacing: 0px border-top-color: rgb(0, 0, 0) border-top-left-radius: 0px border-top-right-radius: 0px @@ -78,12 +117,9 @@ border-top-width: medium bottom: auto box-shadow: none box-sizing: content-box -caption-side: top clear: none clip: auto clip-path: none -clip-rule: nonzero -color: rgb(0, 0, 0) column-count: auto column-gap: auto column-span: none @@ -93,26 +129,15 @@ content-visibility: visible counter-increment: none counter-reset: none counter-set: none -cursor: auto cx: 0px cy: 0px -direction: ltr display: block -fill: rgb(0, 0, 0) -fill-opacity: 1 -fill-rule: nonzero flex-basis: auto flex-direction: row flex-grow: 0 flex-shrink: 1 flex-wrap: nowrap float: none -font-family: serif -font-size: 16px -font-stretch: normal -font-style: normal -font-variant: normal -font-weight: 400 grid-auto-columns: auto grid-auto-flow: row grid-auto-rows: auto @@ -125,8 +150,7 @@ grid-row-start: auto grid-template-areas: grid-template-columns: grid-template-rows: -height: 2159px -image-rendering: auto +height: 2584px inline-size: auto inset-block-end: auto inset-block-start: auto @@ -136,11 +160,6 @@ justify-content: normal justify-items: legacy justify-self: auto left: auto -letter-spacing: normal -line-height: normal -list-style-image: none -list-style-position: outside -list-style-type: disc margin-block-end: 8px margin-block-start: 8px margin-bottom: 8px @@ -151,9 +170,6 @@ margin-right: 8px margin-top: 8px mask: none mask-type: luminance -math-depth: 0 -math-shift: normal -math-style: normal max-height: none max-inline-size: none max-width: none @@ -178,9 +194,7 @@ padding-inline-start: 0px padding-left: 0px padding-right: 0px padding-top: 0px -pointer-events: auto position: static -quotes: auto r: 0px right: auto row-gap: auto @@ -190,21 +204,11 @@ scrollbar-gutter: auto scrollbar-width: auto stop-color: rgb(0, 0, 0) stop-opacity: 1 -stroke: none -stroke-opacity: 1 -stroke-width: 1px table-layout: auto -text-align: start -text-anchor: start text-decoration-color: rgb(0, 0, 0) -text-decoration-line: none text-decoration-style: solid text-decoration-thickness: auto -text-indent: 0px -text-justify: auto text-overflow: clip -text-shadow: none -text-transform: none top: auto transform: none transform-box: view-box @@ -215,11 +219,7 @@ transition-property: all transition-timing-function: ease user-select: auto vertical-align: baseline -visibility: visible -white-space: normal width: 784px -word-spacing: normal -word-wrap: normal x: 0px y: 0px z-index: auto