101 lines
6.1 KiB
Markdown
101 lines
6.1 KiB
Markdown
# Phase 6 investigation
|
|
|
|
All comparisons use the current instrumented harness with matching frontend and
|
|
server from detached worktrees beneath `perf/.tmp`. No production requests.
|
|
Command template (three fresh contexts):
|
|
|
|
```
|
|
node perf/baseline.mjs --runs 3 --browser webkit --profile lte --scenario cold --source-root perf/.tmp/phase6-<variant> --out perf/results/phase6-<variant>.json
|
|
```
|
|
|
|
| Source | Commit | LTE FCP median ms | Wire bytes | app.js positive responses/sample |
|
|
|---|---|---:|---:|---:|
|
|
| Phase 2 | 4950d3e | 1044 | 1191063 | 2 |
|
|
| Immediately before lazy layouts | d98d444 | 1032 | 1191686 | 2 |
|
|
| First lazy-layout cut | 5d6a154 | 1615 | 1106796 | 2 |
|
|
| Phase 3 tip | cd4a25a | 1646 | 1108191 | 2 |
|
|
| Phase 5 tip (same product as Phase 4) | 21c1273 | 1736 | 1097007 | 2 |
|
|
| Phase 5 + worker force-cache | scratch | 1745 | 1097006 | 2 |
|
|
| Phase 5 + parser-owned classic CSS | scratch | 898 | 1097051 | 2 |
|
|
| Phase 5 + classic preload | scratch | 909 | 1097032 | 2 |
|
|
|
|
The adjacent-commit measurements isolate `5d6a154`, not the Phase 4 extraction.
|
|
All three FCP samples, complete proxy waterfalls, and page Resource Timing are
|
|
stored in each result. The first sample often includes startup compression cost;
|
|
it is retained in every median, not discarded.
|
|
|
|
Phase 3 sample 2: common styles finish around 880 ms. The parser-written classic
|
|
stylesheet is discovered at 416 ms but reaches the proxy only at 1434 ms and
|
|
finishes at 1607 ms. FCP is 1646 ms. Phase 5 sample 2: classic reaches the proxy
|
|
at 1540 ms, finishes at 1711 ms, FCP is 1736 ms. Speculatively discovered body
|
|
scripts already occupy the request queue when the selected stylesheet arrives.
|
|
Phase 2 discovers its declarative styles together around 231 ms, FCP 1044 ms.
|
|
|
|
The first service-worker request is at 2458 ms in Phase 3 and 2337 ms in Phase 5,
|
|
AFTER paint. Worker install competition does not explain this FCP regression.
|
|
Font preload URLs match the font CSS; late layout CSS is the final rendering
|
|
barrier. Making classic CSS declarative again removes the delay without changing
|
|
CSS bytes or cascade order. This scratch variant unconditionally applies classic
|
|
and is diagnostic only; the shipping fix must retain selected-layout behavior.
|
|
|
|
The modern synchronizer already uses default fetch caching. Changing it to
|
|
force-cache has no effect: every WebKit sample still transfers app.js twice.
|
|
The page and worker cannot reuse these HTTP-cache responses in this harness.
|
|
A same-build page handoff can reuse the page HTTP cache instead. Worker validation
|
|
must check both the X-Asset-Hash header and SHA-256 of the decoded bytes. It must
|
|
strip compressed transport headers before constructing the cached Response.
|
|
Updates and legacy migration must continue through their existing worker path.
|
|
|
|
The shipping CSS fix is a preload, not an unconditional stylesheet. Its three-run
|
|
FCP is 909 ms; the first classic request reaches the proxy at 250 ms and completes
|
|
at 423 ms. Lazy still applies only the saved layout, in the original cascade order.
|
|
Other selected layouts may speculatively download the small classic stylesheet;
|
|
it never applies or blocks their rendering. No inline script or CSP change.
|
|
|
|
|
|
The page-to-worker prototype successfully delivered bodies, but still transferred
|
|
app.js twice. `phase6-handoff-mode.json` records the two requests: identical URL,
|
|
`Accept-Encoding: gzip, deflate`, no-cors mode and immutable response, but script
|
|
versus empty request destinations. Force-cache in the page did not reuse the
|
|
script body's cache either. This prototype was discarded, not shipped.
|
|
|
|
A fetch preload plus a later fetch also failed the one-body assertion. The
|
|
shipping fix instead starts one cache-first fetch promise in the head loader.
|
|
The final eager app-bootstrap consumes that response, verifies header AND SHA-256,
|
|
and caches it before executing unchanged app.js as a classic script. A specific
|
|
server-generated CSP hash authorizes only those exact bytes; unsafe-inline remains
|
|
absent. DOMContentLoaded boot runs exactly once; the temporary script node and
|
|
response promise are released. Native, insecure HTTP and rollback modes retain
|
|
external classic execution. Only server asset-manifest rendering changed; no
|
|
frontend imports, worker sync algorithm, update flow or playback source changed.
|
|
|
|
The initial owned-response trial passed with one app.js body, FCP 1040 ms and
|
|
981468 wire bytes (one fresh sample; not a final median). Five-run acceptance and
|
|
regression results will be recorded separately. Historical diagnostics retained
|
|
all samples. Full-harness configurations now reset to the base tree before each
|
|
browser/profile, preventing a preceding synthetic update from contaminating the
|
|
next cold build. The historical invalid media fixture remains unchanged: home
|
|
launch only, not autoplay/audio latency.
|
|
|
|
|
|
Self-review added explicit N-1 app boot after eviction: verify the retained body
|
|
and use its exact classic URL through the controlling worker. It never fills the
|
|
new key with old bytes. Stale core execution additionally requires every group
|
|
contract to match the running shell's expectations; a core or feature contract
|
|
change rejects it. Both-engine lazy smoke now changes app bytes, evicts the new
|
|
entry, boots N-1 offline, then repairs the current entry before the existing
|
|
feature pinning/contract/playback checks. No source in app.js changed.
|
|
|
|
|
|
The all-engine inline prototype's completed five-run Chromium/LTE profile had
|
|
cold boot 6748 ms, warm boot 458 ms (Phase 5: 410 ms), offline boot 204 ms, core
|
|
update 870 ms. This was a real warm regression, so the full sweep was interrupted
|
|
before accepting its results. Raw output: perf/.tmp/phase6-inline-chromium-profile.log.
|
|
The native-script controlled variant measured warm 414 ms over five samples.
|
|
Shipping capture is therefore restricted to WebKit (including iOS CriOS); other
|
|
engines preload and retain their native classic-script/code-cache path. Normal
|
|
native cache hits avoid decoding/rehashing; retained core fallback still enforces
|
|
all group contracts. The new worker marks stale responses no-store and strips
|
|
decoded transport headers, preventing browser resource-cache poisoning under a
|
|
new URL. CacheStorage's exact keys and previous entries stay unchanged.
|