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/
This commit is contained in:
Andreas Kling 2024-09-03 17:48:43 +02:00 committed by Andreas Kling
parent 0fab3d3b62
commit 1f5c49f40d
Notes: github-actions[bot] 2024-09-08 07:46:44 +00:00
2 changed files with 93 additions and 98 deletions

View file

@ -136,46 +136,61 @@ enum class PropertyID {
All, All,
)~~~"); )~~~");
Vector<ByteString> shorthand_property_ids; Vector<ByteString> inherited_shorthand_property_ids;
Vector<ByteString> longhand_property_ids; Vector<ByteString> inherited_longhand_property_ids;
Vector<ByteString> noninherited_shorthand_property_ids;
Vector<ByteString> noninherited_longhand_property_ids;
properties.for_each_member([&](auto& name, auto& value) { properties.for_each_member([&](auto& name, auto& value) {
VERIFY(value.is_object()); VERIFY(value.is_object());
if (value.as_object().has("longhands"sv)) bool inherited = value.as_object().get_bool("inherited"sv).value_or(false);
shorthand_property_ids.append(name); if (value.as_object().has("longhands"sv)) {
else if (inherited)
longhand_property_ids.append(name); 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(); // Section order:
auto last_property_id = longhand_property_ids.last(); // 1. inherited shorthand properties
// 2. noninherited shorthand properties
// 3. inherited longhand properties
// 4. noninherited longhand properties
for (auto& name : shorthand_property_ids) { auto first_property_id = inherited_shorthand_property_ids.first();
auto member_generator = generator.fork(); auto last_property_id = noninherited_longhand_property_ids.last();
member_generator.set("name:titlecase", title_casify(name));
member_generator.append(R"~~~( auto emit_properties = [&](auto& property_ids) {
@name:titlecase@, 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) { emit_properties(inherited_shorthand_property_ids);
auto member_generator = generator.fork(); emit_properties(noninherited_shorthand_property_ids);
member_generator.set("name:titlecase", title_casify(name)); emit_properties(inherited_longhand_property_ids);
emit_properties(noninherited_longhand_property_ids);
member_generator.append(R"~~~(
@name:titlecase@,
)~~~");
}
generator.set("first_property_id", title_casify(first_property_id)); generator.set("first_property_id", title_casify(first_property_id));
generator.set("last_property_id", title_casify(last_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("first_longhand_property_id", title_casify(inherited_longhand_property_ids.first()));
generator.set("last_shorthand_property_id", title_casify(shorthand_property_ids.last())); 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("first_inherited_shorthand_property_id", title_casify(inherited_shorthand_property_ids.first()));
generator.set("last_longhand_property_id", title_casify(longhand_property_ids.last())); 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"~~~( generator.append(R"~~~(
}; };
@ -247,8 +262,10 @@ bool property_affects_stacking_context(PropertyID);
constexpr PropertyID first_property_id = PropertyID::@first_property_id@; constexpr PropertyID first_property_id = PropertyID::@first_property_id@;
constexpr PropertyID last_property_id = PropertyID::@last_property_id@; constexpr PropertyID last_property_id = PropertyID::@last_property_id@;
constexpr PropertyID first_shorthand_property_id = PropertyID::@first_shorthand_property_id@; constexpr PropertyID first_inherited_shorthand_property_id = PropertyID::@first_inherited_shorthand_property_id@;
constexpr PropertyID last_shorthand_property_id = PropertyID::@last_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 first_longhand_property_id = PropertyID::@first_longhand_property_id@;
constexpr PropertyID last_longhand_property_id = PropertyID::@last_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) bool is_inherited_property(PropertyID property_id)
{ {
switch (property_id) { if (property_id >= first_inherited_shorthand_property_id && property_id <= last_inherited_longhand_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@:
return true; return true;
)~~~"); if (property_id >= first_inherited_longhand_property_id && property_id <= last_inherited_longhand_property_id)
} return true;
}); return false;
generator.append(R"~~~(
default:
return false;
}
} }
bool property_affects_layout(PropertyID property_id) bool property_affects_layout(PropertyID property_id)

View file

@ -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-content: normal
-webkit-align-items: normal -webkit-align-items: normal
-webkit-align-self: auto -webkit-align-self: auto
@ -26,14 +69,12 @@
-webkit-justify-content: normal -webkit-justify-content: normal
-webkit-mask: none -webkit-mask: none
-webkit-order: 0 -webkit-order: 0
-webkit-text-fill-color: rgb(0, 0, 0)
-webkit-transform: none -webkit-transform: none
-webkit-transform-origin: 50% 50% -webkit-transform-origin: 50% 50%
-webkit-transition-delay: 0s -webkit-transition-delay: 0s
-webkit-transition-duration: 0s -webkit-transition-duration: 0s
-webkit-transition-property: all -webkit-transition-property: all
-webkit-transition-timing-function: ease -webkit-transition-timing-function: ease
accent-color: auto
align-content: normal align-content: normal
align-items: normal align-items: normal
align-self: auto align-self: auto
@ -62,14 +103,12 @@ border-bottom-left-radius: 0px
border-bottom-right-radius: 0px border-bottom-right-radius: 0px
border-bottom-style: none border-bottom-style: none
border-bottom-width: medium border-bottom-width: medium
border-collapse: separate
border-left-color: rgb(0, 0, 0) border-left-color: rgb(0, 0, 0)
border-left-style: none border-left-style: none
border-left-width: medium border-left-width: medium
border-right-color: rgb(0, 0, 0) border-right-color: rgb(0, 0, 0)
border-right-style: none border-right-style: none
border-right-width: medium border-right-width: medium
border-spacing: 0px
border-top-color: rgb(0, 0, 0) border-top-color: rgb(0, 0, 0)
border-top-left-radius: 0px border-top-left-radius: 0px
border-top-right-radius: 0px border-top-right-radius: 0px
@ -78,12 +117,9 @@ border-top-width: medium
bottom: auto bottom: auto
box-shadow: none box-shadow: none
box-sizing: content-box box-sizing: content-box
caption-side: top
clear: none clear: none
clip: auto clip: auto
clip-path: none clip-path: none
clip-rule: nonzero
color: rgb(0, 0, 0)
column-count: auto column-count: auto
column-gap: auto column-gap: auto
column-span: none column-span: none
@ -93,26 +129,15 @@ content-visibility: visible
counter-increment: none counter-increment: none
counter-reset: none counter-reset: none
counter-set: none counter-set: none
cursor: auto
cx: 0px cx: 0px
cy: 0px cy: 0px
direction: ltr
display: block display: block
fill: rgb(0, 0, 0)
fill-opacity: 1
fill-rule: nonzero
flex-basis: auto flex-basis: auto
flex-direction: row flex-direction: row
flex-grow: 0 flex-grow: 0
flex-shrink: 1 flex-shrink: 1
flex-wrap: nowrap flex-wrap: nowrap
float: none 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-columns: auto
grid-auto-flow: row grid-auto-flow: row
grid-auto-rows: auto grid-auto-rows: auto
@ -125,8 +150,7 @@ grid-row-start: auto
grid-template-areas: grid-template-areas:
grid-template-columns: grid-template-columns:
grid-template-rows: grid-template-rows:
height: 2159px height: 2584px
image-rendering: auto
inline-size: auto inline-size: auto
inset-block-end: auto inset-block-end: auto
inset-block-start: auto inset-block-start: auto
@ -136,11 +160,6 @@ justify-content: normal
justify-items: legacy justify-items: legacy
justify-self: auto justify-self: auto
left: 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-end: 8px
margin-block-start: 8px margin-block-start: 8px
margin-bottom: 8px margin-bottom: 8px
@ -151,9 +170,6 @@ margin-right: 8px
margin-top: 8px margin-top: 8px
mask: none mask: none
mask-type: luminance mask-type: luminance
math-depth: 0
math-shift: normal
math-style: normal
max-height: none max-height: none
max-inline-size: none max-inline-size: none
max-width: none max-width: none
@ -178,9 +194,7 @@ padding-inline-start: 0px
padding-left: 0px padding-left: 0px
padding-right: 0px padding-right: 0px
padding-top: 0px padding-top: 0px
pointer-events: auto
position: static position: static
quotes: auto
r: 0px r: 0px
right: auto right: auto
row-gap: auto row-gap: auto
@ -190,21 +204,11 @@ scrollbar-gutter: auto
scrollbar-width: auto scrollbar-width: auto
stop-color: rgb(0, 0, 0) stop-color: rgb(0, 0, 0)
stop-opacity: 1 stop-opacity: 1
stroke: none
stroke-opacity: 1
stroke-width: 1px
table-layout: auto table-layout: auto
text-align: start
text-anchor: start
text-decoration-color: rgb(0, 0, 0) text-decoration-color: rgb(0, 0, 0)
text-decoration-line: none
text-decoration-style: solid text-decoration-style: solid
text-decoration-thickness: auto text-decoration-thickness: auto
text-indent: 0px
text-justify: auto
text-overflow: clip text-overflow: clip
text-shadow: none
text-transform: none
top: auto top: auto
transform: none transform: none
transform-box: view-box transform-box: view-box
@ -215,11 +219,7 @@ transition-property: all
transition-timing-function: ease transition-timing-function: ease
user-select: auto user-select: auto
vertical-align: baseline vertical-align: baseline
visibility: visible
white-space: normal
width: 784px width: 784px
word-spacing: normal
word-wrap: normal
x: 0px x: 0px
y: 0px y: 0px
z-index: auto z-index: auto