Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 3a5e8ecc480bd0dda46bfb68fe773346fa386c0d
https://github.com/WebKit/WebKit/commit/3a5e8ecc480bd0dda46bfb68fe773346fa386c0d
Author: Nikolas Zimmermann <[email protected]>
Date: 2026-08-31 (Mon, 31 Aug 2026)
Changed paths:
A LayoutTests/fast/css/display-contents-no-empty-text-update-expected.txt
A LayoutTests/fast/css/display-contents-no-empty-text-update.html
A LayoutTests/fast/css/display-contents-text-wrapper-removal-expected.html
A LayoutTests/fast/css/display-contents-text-wrapper-removal.html
M Source/WebCore/rendering/RenderText.h
M Source/WebCore/style/StyleTreeResolver.cpp
Log Message:
-----------
Redundant text updates for every "display: contents" text child
https://bugs.webkit.org/show_bug.cgi?id=322479
Reviewed by Antti Koivisto.
Profiling a Lit-based Web Component application showed up dozens of useless
TextUpdates per style recalc and component, related to the <slot> element
usage. A <slot> element is a placeholder inside a Web Component that is filled
with the markup passed in when the component is used. That markup is placed
below the slot element, and it includes the newlines and indentation between
the elements it passes in. Furthermore a <slot> element uses "display: contents"
and each of those whitespace text nodes got a TextUpdate on every style
resolution:
TreeResolver::resolveComposedTree() unconditionally created a TextUpdate for
every text child of a "display: contents" element.
An element with "display: contents" has no renderer of its own - no box is
generated
by definition. But its text children still need a style for rendering. We
compute
one for them, pretending each text node is wrapped in an unstyled span. That
wrapper
style is only interesting if it differs from the style of the nearest ancestor
that
does have a renderer. If it doesn't differ, then there is nothing to update.
However, the old code looked at the display value of the text nodes parent and
created
an update for every "display: contents" parent it found. That value says
nothing about
whether anything changed. The wrapper style is what actually changes, so decide
on
that instead: compute the wrapper style first, and create a TextUpdate only if
createInheritedDisplayContentsStyleIfNeeded() returned a non-null style.
One exception is removal: A wrapper that is no longer needed only disappears if
RenderTreeUpdater::updateTextRenderer() sees a TextUpdate for that text, so keep
creating one while the old wrapper is still there.
Cover both scenarios with two new tests.
Tests: fast/css/display-contents-no-empty-text-update.html
fast/css/display-contents-text-wrapper-removal.html
* LayoutTests/fast/css/display-contents-no-empty-text-update-expected.txt:
Added.
* LayoutTests/fast/css/display-contents-no-empty-text-update.html: Added.
Counts internals.lastStyleUpdateSize, including once on a <slot> with slotted
whitespace between inline children, and once on a <slot> with slotted whitespace
between block children, where that whitespace has no renderer at all. Without
this
change the two non-inherited cases are 2 instead of 1.
* LayoutTests/fast/css/display-contents-text-wrapper-removal-expected.html:
Added.
* LayoutTests/fast/css/display-contents-text-wrapper-removal.html: Added.
* Source/WebCore/rendering/RenderText.h:
(WebCore::RenderText::hasInlineWrapperForDisplayContents const):
* Source/WebCore/style/StyleTreeResolver.cpp:
(WebCore::Style::TreeResolver::resolveComposedTree):
Canonical link: https://commits.webkit.org/320144@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications