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,
)~~~");
Vector<ByteString> shorthand_property_ids;
Vector<ByteString> longhand_property_ids;
Vector<ByteString> inherited_shorthand_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) {
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)

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-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