Add minimal reproduction of compositor bug

This commit is contained in:
2026-07-22 01:51:22 +10:00
parent c27e5906ca
commit d28b09dc21
2 changed files with 334 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
# WebKit nested composite-transform frame pacing reproduction
This is a dependency-free reproduction for an iOS WebKit frame-pacing issue involving two nested animation clocks:
- A route-sized parent surface whose `translate3d()` progress is updated by `requestAnimationFrame`.
- A child with an infinite CSS `rotate()` animation, drawn as a rounded border spinner.
On the originating device, spinner durations within part of the `0.5s``1.1s` range produced regular 3334 ms rAF gaps, while durations outside that band were smooth. The workload per frame is effectively unchanged, making the duration-dependent behavior unexpected.
## Run
Open `index.html` directly. The reproduction is a single, self-contained HTML file and works from a `file://` URL without a server.
To test it through a local HTTP server instead, run this from the repository root:
```sh
npx vite external/bugs/composite-transform
```
This directory is independent of the Vue demo and has no build step or runtime dependencies. The CSS, test scene, controls, and measurement code are all in `index.html`, so that file can be attached directly to a browser bug report.
## Protocol
1. Do not scroll or touch the page while a sample is running.
2. Run **Sweep 0.51.1 s** with **rAF-driven** selected and **Spinner enabled** checked.
3. Repeat with **Static translate3d parent**.
4. Repeat with **No parent transform**.
5. Clear **Spinner enabled** and run the sweep as a control.
Each duration runs for 1.8 seconds. In the rAF-parent case, the incoming route moves for 700 ms and then remains stationary for the rest of the measurement.
## Expected
Changing only `animation-duration` should alter angular velocity, not cause a stable 60 Hz page to begin missing display deadlines. The rAF stream should remain close to 16.7 ms throughout the sweep on a 60 Hz device.
## Actual observation in the source application
The problematic sample showed:
- A 16 ms baseline.
- Repeated 3334 ms gaps during the route transition.
- The same gaps continuing while the parent was stationary and the spinner remained visible.
- Normal pacing after the spinner was removed from the DOM.
- No route-loading delay, JavaScript long task, or layout shift correlated with the gaps.
The reproduction intentionally contains no Vue, Vue Router, Suspense, application store, network request, or service-worker caching logic in its measured path.