Skip to content

test(Popover): the rendering proof waits for the content to settle - #10326

Merged
cixzhang merged 4 commits into
meta:mainfrom
vjeux:uikit/c27-popover-590-content-settles
Nov 6, 2026
Merged

cixzhang merged 4 commits into
meta:mainfrom
vjeux:uikit/c27-popover-590-content-settles

Conversation

@vjeux

@vjeux vjeux commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Maintainer impact

The Popover rendering proof fails under load: 2 Layouts at +417 ms in #10169's CI.

Intended invariant

component:Popover PR4: "On a page with no other frame work, the touch growth and shrink do no Layout or Paint per frame".

Cause

  • Each switch's motion engine sets an inline --astryx-motion-will-change-after: opacity at story mount and removes it 500 ms later, about 285 ms into the growth, laying out the anchored layer (the CI shape); late timers move it past 400 ms.
  • Each motion's start also measures the touch hit areas (layout reads, then inset writes); a 360 ms stall would move that in too.
  • Product impact: invisible. The demote costs about 2 ms of main thread, changes no pixel (0 of 31,000, growth held), and delays no compositor frame (longest gap 19 ms vs 18 without).

Change

One test file, four commits, +123 −11:

  • Before the open, the proof polls (50 ms, up to 10 s) until no content element holds an inline motion promotion; computed will-change stays opacity under touch.
  • Each window starts at 400 ms, or after the frame drawing the last of the hit areas' new insets if later, and must span 300 ms.

Review bar

first determine whether the 2 Layouts at +417 ms are a real forced layout from the Popover group's new code (a layout read during the touch motion), which makes it a product fix, or test timing (an unrelated layout counted in the window), which makes it a test fix that attributes layouts to their source. Red-first either way; never relax "no Layout or Paint per frame".

  • Popover forced layout: ruled out; a test-only fix removes both sources; red-first: Evidence; toBe(0) unchanged.

Evidence

  • Failure before the change: arms fail 3 of 3: 466ea9b (a 450 ms block 100 ms in) on main, Layout 2; b90572b (the block after the first frame) on the first commit, Layout 6; 01c589c (that block, one control a frame) on the third, Layout 6.
  • Success after the change: at the head, those blocks pass (5e5848d, 8c8ad10 3 of 3; b292681 5 of 5), the proof passes 10 of 10 under each of three loads, Chromium 33 of 33; WebKit 26, 7 skipped, twice.
  • Strictness: 86f45f3 (a switch style write 600 ms in) and 9342b76 (a 900 ms early block, on the floor) fail 3 of 3.
  • No product or CI changes.

Scope

  • No intended public API, product behavior, visual direction, or policy change.
  • Product changes discovered during the work were removed or split.
  • Public text and artifacts contain no internal Meta context.

Testing

pnpm build && pnpm storybook:build
pnpm exec playwright test --config playwright.interaction.config.ts --project=chromium packages/core/src/Popover/__tests__/PopoverTouchMotion.interaction.browser.spec.ts -g "no Layout or Paint per frame" --repeat-each=10
taskset -c 2,3 pnpm exec playwright test --config playwright.interaction.config.ts --project=chromium --workers=1 packages/core/src/Popover/__tests__/PopoverTouchMotion.interaction.browser.spec.ts -g "no Layout or Paint per frame" --repeat-each=10

@vercel

vercel Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astryx Ready Ready Preview Nov 6, 2026 7:23pm UTC

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Nov 6, 2026
@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

🔎 Preview · 51a3e06

Storybook · Sandbox · built from this PR's head

Modified components

Component Size LoC Visual · A11y · RTL
Popover · Storybook 78.7 kB (0) · 13.4 kB CSS (0) 1,488 (0) ✓ · ✓ · ✓

Package size: no published package changed; no new dependencies.

API changes: none in this pull request

Committed API report behind this build: cli 19 rows, core 24 rows; run pnpm api:report.

Touched components checked; add ci:run-visual, ci:run-a11y or ci:run-rtl to run the full suites.


Generated by PR Enrichment workflow | View full report

@cixzhang cixzhang added the ci:run A maintainer lets this outside contributor's pull request run CI (AST-030 FR17) label Nov 6, 2026
@cixzhang

cixzhang commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

/approve-spec dbaa9a4

@astracat-bot

astracat-bot Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

AI review status for this pull request.

Review status Updated
🟢 Reviewed (for maintainers only) Nov 6, 2026, 7:27 PM UTC

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes requested: one fix in the new window-start logic.

  • The rendering windows wait only for the first hit-area inset write (PopoverTouchMotion.interaction.browser.spec.ts:726-729), so when a stall delays the hit-area pass and its 4 ms frame budget (utils/hitArea.ts:642) splits the three Switches across frames, the later writes still count in the presentation window (reproduced: Layout 6, Paint 2); extend the start through each write that lands before the previous one has drawn.

Otherwise the proof stays strict, since both zero assertions and the frame-loop control are unchanged, and a stall that only delays the pass now leaves the window clean where the base version fails. Minor: the first commit's message still describes a computed will-change check, but the code reads inline styles. CI has not run yet because this pull request is a draft.

[Automated review]

vjeux added 4 commits November 6, 2026 10:51
Each switch in the story promotes its fades as the story mounts and
ends that promotion 500 ms later, with a style write. The rendering
proof opens the popover about 215 ms after the mount, so the write
lands in the growth, where Chromium lays out the anchored layer for
it. On a loaded machine it lands inside the counted window.

Before it opens the popover, the proof now waits until no element in
the content holds a motion promotion in its inline styles: a
will-change, or the custom property that promotes a ::before or
::after. The counts stay strict: 0 Layout and 0 Paint.
Each motion's start measures the content's touch hit areas: layout
reads, then a style write. Both lay out the anchored layer, and a
stalled machine can delay them past the window's 400 ms start. Each
window now starts no sooner than the frame that draws those insets,
seen through a mutation observer, which reads no layout.
A stall can push the hit areas' insets frame so late that little or
none of a window is left, and an empty window counts 0 Layout and 0
Paint. Each window must now span at least 300 ms, or the proof fails
and says when the hit areas drew.
The hit areas' pass measures a few controls a frame, within a 4 ms
budget, so under load its inset writes spread over several frames. A
window now starts after the frame that draws the last write of the
pass: each write that lands before the previous one has drawn joins
it.
@vjeux
vjeux force-pushed the uikit/c27-popover-590-content-settles branch from dbaa9a4 to 51a3e06 Compare November 6, 2026 19:12
@cixzhang

cixzhang commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

/approve-spec 51a3e06

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved pending CI: CI has not run on this head yet because the pull request is a draft, and marking it ready for review starts it.

The rendering windows now start after the last inset write of the hit-area pass, so a stall that spreads the pass over several frames leaves the presentation window at 0 Layout and 0 Paint, where the base version counts 10. Both zero assertions and the frame-loop control are unchanged, so the proof stays strict.

[Automated review]

@vjeux
vjeux marked this pull request as ready for review November 6, 2026 19:29
@cixzhang
cixzhang merged commit 39f2441 into meta:main Nov 6, 2026
122 checks passed
@vjeux
vjeux deleted the uikit/c27-popover-590-content-settles branch November 6, 2026 20:02

This branch was successfully deployed

1 active deployment
Preview — 51a3e06e Deployed Nov 6, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:run A maintainer lets this outside contributor's pull request run CI (AST-030 FR17) CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants