fix: keep effective style guards out of host markup - #497
Open
Mohamed Mansour (mohamedmansour) wants to merge 2 commits into
Open
fix: keep effective style guards out of host markup#497Mohamed Mansour (mohamedmansour) wants to merge 2 commits into
Mohamed Mansour (mohamedmansour) wants to merge 2 commits into
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: dd179fee-1085-4b47-b973-c065a7e089a6
Mohamed Mansour (mohamedmansour)
requested review from
Bang Lee (Qusic),
Akrosh Gandhi (akroshg),
Jane Chu (janechu) and
mcritzjam
August 27, 2026 04:21
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Root cause
The 0.0.26 mount guard always wrote temporary
transition-propertyandvisibilitydeclarations to the custom-element host even when its stronger first-layer shadow rule had parsed successfully. Author code serializing live DOM during the pending mount could persist those framework-owned declarations as input.Design rationale
CSS cascading rules give important declarations from the inner shadow context precedence over outer author declarations, including inline important styles. Important declarations also reverse cascade-layer order, so the prepended anonymous first layer wins over later component layers. Chromium, Firefox, and WebKit all confirmed the guard computes
transition-property: noneandvisibility: hiddenwithout changing host markup.A CSSOM parse check is preferable to a computed-style probe: the guard CSS and selector are framework constants, while
getComputedStyle()would force style resolution on every mount and cannot distinguish the guard from authored hidden styles. If CSP or parsing prevents the sheet from becoming available, the existing inline fallback remains and content stays detached until linked styles settle.Regression evidence
Before the production fix, the new browser test failed because
outerHTMLchanged from the authored style to includetransition-property: none !important; visibility: hidden !importantwhile the external stylesheets were pending.Performance
Chromium microbenchmarks alternated the pre-fix and fixed implementations and included a pending-style flush plus guard release:
P95 improved from 12.1 ms to 6.4 ms and from 11.2 ms to 7.7 ms respectively. The common path removes four inline-style reads, two writes, restoration reads/writes, mutation-observer visibility, and host capture from the pending release closure.
The rare unavailable-shadow-guard fallback adds exact style-attribute restoration. An isolated 5,000-fallback microbenchmark added 0.5 ms with no authored style and 1.2 ms with authored values, about 0.10-0.24 microseconds per fallback. A 3,000-pending-mount CDP sample reduced median V8 heap by about 33 bytes per mount and kept the DOM node count identical; native/embedder heap readings were noisy and are not used as a claim.
The minified production framework bundle changes from 78,447 to 78,588 bytes, or 24,533 to 24,573 bytes gzip: +141 raw / +40 gzip bytes.
Validation
cargo xtask check