Document incremental sync verification and performance gaps
This commit is contained in:
@@ -181,3 +181,34 @@ which receive hashed URLs as HTML scripts. Font preloads retain plain URLs to ma
|
||||
`fonts.css`; the webmanifest and its icon URLs also stay plain and precached.
|
||||
`piano-engine.mjs` is manifested but is historically absent from SHELL; this
|
||||
existing offline piano limitation is deferred to the loader phase.
|
||||
|
||||
## Phase 2 incremental-sync verification
|
||||
|
||||
The current migration harness verifies the production page's own ready fast path
|
||||
into `ytplayer-assets`: no `__ytpfresh` downloads, no reload before Refresh UI,
|
||||
one banner/reload, an open N-1 tab, playback guard, incremental refresh after
|
||||
an eviction, and offline launch. It preserves the legacy user-triggered reload
|
||||
exception. Async CacheStorage/registration conditions are polled with awaited
|
||||
`page.evaluate`; Playwright's `waitForFunction` does not poll async predicates.
|
||||
|
||||
```bash
|
||||
node perf/migration.mjs --browser all --profile lossy
|
||||
node perf/migration.mjs --browser all --profile unthrottled
|
||||
node perf/baseline.mjs --runs 1 --browser all --profile lte --scenario all \
|
||||
--out perf/results/phase2-final-2026-10-07.json \
|
||||
--compare perf/results/after-phase0-2026-10-07.json
|
||||
ASSET_SYNC=0 node perf/baseline.mjs --runs 1 --browser all --profile lte \
|
||||
--scenario offline --out perf/results/phase2-rollback-2026-10-07.json
|
||||
ASSET_HASHING=0 node perf/baseline.mjs --runs 1 --browser all --profile lte \
|
||||
--scenario offline --out perf/results/phase2-hashing-rollback-2026-10-07.json
|
||||
```
|
||||
|
||||
Results now include response paths/statuses and compressed response-body bytes
|
||||
for cold/update runs. The total includes service-worker script checks/imports;
|
||||
inspect individual responses to distinguish those from app asset downloads.
|
||||
Migration results are `phase2-migration-<profile>-2026-10-07.json`.
|
||||
`ASSET_SYNC=0` selects the legacy path while preserving the persistent utility
|
||||
cache. `ASSET_HASHING=0` also selects legacy sync because single-tag URLs cannot
|
||||
pass per-file hash checks. Current assets.json groups all block; idle loading and
|
||||
lazy parsing await Phase 3. Incremental mode now caches the manifested
|
||||
`piano-engine.mjs` even though it remains absent from the legacy SHELL.
|
||||
|
||||
2082
perf/results/phase2-final-2026-10-07.json
Normal file
2082
perf/results/phase2-final-2026-10-07.json
Normal file
File diff suppressed because it is too large
Load Diff
131
perf/results/phase2-hashing-rollback-2026-10-07.json
Normal file
131
perf/results/phase2-hashing-rollback-2026-10-07.json
Normal file
@@ -0,0 +1,131 @@
|
||||
{
|
||||
"date": "2026-10-07T16:00:49.668Z",
|
||||
"commit": "bb446c717f92ef912f5000ddc757b9d1071120dc",
|
||||
"runsConfigured": 1,
|
||||
"browsers": {
|
||||
"chromium": {
|
||||
"lte": {
|
||||
"offline": {
|
||||
"requestCount": {
|
||||
"median": 0,
|
||||
"min": 0,
|
||||
"max": 0,
|
||||
"values": [
|
||||
0
|
||||
]
|
||||
},
|
||||
"wireBytes": {
|
||||
"median": 0,
|
||||
"min": 0,
|
||||
"max": 0,
|
||||
"values": [
|
||||
0
|
||||
]
|
||||
},
|
||||
"fcp": {
|
||||
"median": 76,
|
||||
"min": 76,
|
||||
"max": 76,
|
||||
"values": [
|
||||
76
|
||||
]
|
||||
},
|
||||
"lcp": {
|
||||
"median": 300,
|
||||
"min": 300,
|
||||
"max": 300,
|
||||
"values": [
|
||||
300
|
||||
]
|
||||
},
|
||||
"domContentLoaded": {
|
||||
"median": 233,
|
||||
"min": 233,
|
||||
"max": 233,
|
||||
"values": [
|
||||
233
|
||||
]
|
||||
},
|
||||
"bootDone": {
|
||||
"median": 279,
|
||||
"min": 279,
|
||||
"max": 279,
|
||||
"values": [
|
||||
279
|
||||
]
|
||||
},
|
||||
"reloadDuration": {
|
||||
"median": 306,
|
||||
"min": 306,
|
||||
"max": 306,
|
||||
"values": [
|
||||
306
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"webkit": {
|
||||
"lte": {
|
||||
"offline": {
|
||||
"requestCount": {
|
||||
"median": 0,
|
||||
"min": 0,
|
||||
"max": 0,
|
||||
"values": [
|
||||
0
|
||||
]
|
||||
},
|
||||
"wireBytes": {
|
||||
"median": 0,
|
||||
"min": 0,
|
||||
"max": 0,
|
||||
"values": [
|
||||
0
|
||||
]
|
||||
},
|
||||
"fcp": {
|
||||
"median": 129,
|
||||
"min": 129,
|
||||
"max": 129,
|
||||
"values": [
|
||||
129
|
||||
]
|
||||
},
|
||||
"lcp": {
|
||||
"median": 158,
|
||||
"min": 158,
|
||||
"max": 158,
|
||||
"values": [
|
||||
158
|
||||
]
|
||||
},
|
||||
"domContentLoaded": {
|
||||
"median": 117,
|
||||
"min": 117,
|
||||
"max": 117,
|
||||
"values": [
|
||||
117
|
||||
]
|
||||
},
|
||||
"bootDone": {
|
||||
"median": 153,
|
||||
"min": 153,
|
||||
"max": 153,
|
||||
"values": [
|
||||
153
|
||||
]
|
||||
},
|
||||
"reloadDuration": {
|
||||
"median": 165,
|
||||
"min": 165,
|
||||
"max": 165,
|
||||
"values": [
|
||||
165
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
41
perf/results/phase2-migration-lossy-2026-10-07.json
Normal file
41
perf/results/phase2-migration-lossy-2026-10-07.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"commit": "b77938a",
|
||||
"results": [
|
||||
{
|
||||
"browser": "chromium",
|
||||
"oldTag": "1175f1a1d2c1",
|
||||
"newTag": "4f7090fff60c",
|
||||
"banners": 1,
|
||||
"updateReloads": 1,
|
||||
"cachedFiles": 92,
|
||||
"durationMs": 27514,
|
||||
"wireBytes": 622009,
|
||||
"offline": true,
|
||||
"legacyURLs": 21,
|
||||
"profile": "lossy",
|
||||
"userInitiatedOnly": true,
|
||||
"playbackGuard": true,
|
||||
"evictionRepair": true,
|
||||
"incrementalRefresh": true,
|
||||
"offlineTransportErrors": 0
|
||||
},
|
||||
{
|
||||
"browser": "webkit",
|
||||
"oldTag": "1175f1a1d2c1",
|
||||
"newTag": "4f7090fff60c",
|
||||
"banners": 1,
|
||||
"updateReloads": 1,
|
||||
"cachedFiles": 92,
|
||||
"durationMs": 19558,
|
||||
"wireBytes": 731221,
|
||||
"offline": true,
|
||||
"legacyURLs": 21,
|
||||
"profile": "lossy",
|
||||
"userInitiatedOnly": true,
|
||||
"playbackGuard": true,
|
||||
"evictionRepair": true,
|
||||
"incrementalRefresh": true,
|
||||
"offlineTransportErrors": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
41
perf/results/phase2-migration-unthrottled-2026-10-07.json
Normal file
41
perf/results/phase2-migration-unthrottled-2026-10-07.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"commit": "b77938a",
|
||||
"results": [
|
||||
{
|
||||
"browser": "chromium",
|
||||
"oldTag": "1175f1a1d2c1",
|
||||
"newTag": "4f7090fff60c",
|
||||
"banners": 1,
|
||||
"updateReloads": 1,
|
||||
"cachedFiles": 92,
|
||||
"durationMs": 10811,
|
||||
"wireBytes": 630657,
|
||||
"offline": true,
|
||||
"legacyURLs": 21,
|
||||
"profile": "unthrottled",
|
||||
"userInitiatedOnly": true,
|
||||
"playbackGuard": true,
|
||||
"evictionRepair": true,
|
||||
"incrementalRefresh": true,
|
||||
"offlineTransportErrors": 0
|
||||
},
|
||||
{
|
||||
"browser": "webkit",
|
||||
"oldTag": "1175f1a1d2c1",
|
||||
"newTag": "4f7090fff60c",
|
||||
"banners": 1,
|
||||
"updateReloads": 1,
|
||||
"cachedFiles": 92,
|
||||
"durationMs": 9283,
|
||||
"wireBytes": 744401,
|
||||
"offline": true,
|
||||
"legacyURLs": 21,
|
||||
"profile": "unthrottled",
|
||||
"userInitiatedOnly": true,
|
||||
"playbackGuard": true,
|
||||
"evictionRepair": true,
|
||||
"incrementalRefresh": true,
|
||||
"offlineTransportErrors": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
131
perf/results/phase2-rollback-2026-10-07.json
Normal file
131
perf/results/phase2-rollback-2026-10-07.json
Normal file
@@ -0,0 +1,131 @@
|
||||
{
|
||||
"date": "2026-10-07T15:55:07.011Z",
|
||||
"commit": "54a07a0a2ae1711e441545b208c45c55b3318963",
|
||||
"runsConfigured": 1,
|
||||
"browsers": {
|
||||
"chromium": {
|
||||
"lte": {
|
||||
"offline": {
|
||||
"requestCount": {
|
||||
"median": 0,
|
||||
"min": 0,
|
||||
"max": 0,
|
||||
"values": [
|
||||
0
|
||||
]
|
||||
},
|
||||
"wireBytes": {
|
||||
"median": 0,
|
||||
"min": 0,
|
||||
"max": 0,
|
||||
"values": [
|
||||
0
|
||||
]
|
||||
},
|
||||
"fcp": {
|
||||
"median": 72,
|
||||
"min": 72,
|
||||
"max": 72,
|
||||
"values": [
|
||||
72
|
||||
]
|
||||
},
|
||||
"lcp": {
|
||||
"median": 72,
|
||||
"min": 72,
|
||||
"max": 72,
|
||||
"values": [
|
||||
72
|
||||
]
|
||||
},
|
||||
"domContentLoaded": {
|
||||
"median": 225,
|
||||
"min": 225,
|
||||
"max": 225,
|
||||
"values": [
|
||||
225
|
||||
]
|
||||
},
|
||||
"bootDone": {
|
||||
"median": 249,
|
||||
"min": 249,
|
||||
"max": 249,
|
||||
"values": [
|
||||
249
|
||||
]
|
||||
},
|
||||
"reloadDuration": {
|
||||
"median": 262,
|
||||
"min": 262,
|
||||
"max": 262,
|
||||
"values": [
|
||||
262
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"webkit": {
|
||||
"lte": {
|
||||
"offline": {
|
||||
"requestCount": {
|
||||
"median": 0,
|
||||
"min": 0,
|
||||
"max": 0,
|
||||
"values": [
|
||||
0
|
||||
]
|
||||
},
|
||||
"wireBytes": {
|
||||
"median": 0,
|
||||
"min": 0,
|
||||
"max": 0,
|
||||
"values": [
|
||||
0
|
||||
]
|
||||
},
|
||||
"fcp": {
|
||||
"median": 109,
|
||||
"min": 109,
|
||||
"max": 109,
|
||||
"values": [
|
||||
109
|
||||
]
|
||||
},
|
||||
"lcp": {
|
||||
"median": 138,
|
||||
"min": 138,
|
||||
"max": 138,
|
||||
"values": [
|
||||
138
|
||||
]
|
||||
},
|
||||
"domContentLoaded": {
|
||||
"median": 101,
|
||||
"min": 101,
|
||||
"max": 101,
|
||||
"values": [
|
||||
101
|
||||
]
|
||||
},
|
||||
"bootDone": {
|
||||
"median": 133,
|
||||
"min": 133,
|
||||
"max": 133,
|
||||
"values": [
|
||||
133
|
||||
]
|
||||
},
|
||||
"reloadDuration": {
|
||||
"median": 145,
|
||||
"min": 145,
|
||||
"max": 145,
|
||||
"values": [
|
||||
145
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
43
plans/phase2-report.md
Normal file
43
plans/phase2-report.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Phase 2 report
|
||||
|
||||
Shipped on `codex/phase2`: plan `a1f16f2`; incremental sync/playback guards
|
||||
`54a07a0`; atomic state, exact hash rejection and retention `5b25cca`;
|
||||
single-tag rollback compatibility `bb446c7`; migration verification `5d1e5ec`;
|
||||
fail-closed status handling `9240456`.
|
||||
|
||||
Persistent `ytplayer-assets` stores verified exact URLs and current/previous
|
||||
manifests. Downloads resume, use six workers/three attempts, and publish only
|
||||
complete blocking sets. Activation retains N-1 changed/removed files, prunes
|
||||
N-2, then deletes legacy caches; quota is logged. All current groups block;
|
||||
lazy parsing/background warming await Phase 3.
|
||||
|
||||
Server gaps addressed: inject ASSET_SYNC and the hashed sync-core import,
|
||||
hash final worker bytes, compress manifest responses while preserving build
|
||||
ETags. ASSET_SYNC=0 selects legacy sync; ASSET_HASHING=0 also selects legacy.
|
||||
|
||||
Verification: 168 frontend/181 server tests pass without skips. Chromium/WebKit
|
||||
migration passes with and without stalls using actual b77938a code: ready:true,
|
||||
zero legacy refresh downloads, one banner/user-triggered reload, N-1 open tab,
|
||||
eviction repair, incremental refresh and offline boot. Both rollback flags
|
||||
pass offline browser checks. Async polling fixes the Playwright harness race.
|
||||
|
||||
Accepted legacy exception: b77938a retains its four-second timer after the USER
|
||||
presses Refresh UI and does not report playback. New pages guard playback,
|
||||
offer explicit override and post PLAYING; workers defer known-playing requests
|
||||
and never call skipWaiting during installation.
|
||||
|
||||
Final one-run LTE measurements (`phase2-final-2026-10-07.json`, Chromium/WebKit):
|
||||
JS updates 155,648/189,354 bytes versus 611,338/680,822; CSS 31,476/30,545 versus
|
||||
611,476/680,831. Sync fetches changed app/style + index/manifest; fonts/icons transfer
|
||||
zero bytes. Browser worker checks add overhead: Chromium downloads sw.js twice;
|
||||
WebKit also downloads the unchanged imported core. Thus total CSS exceeds
|
||||
30,000 bytes.
|
||||
|
||||
Cold bytes: 624,762/1,191,130 versus 1,040,158/1,180,749. Chromium transfers app.js
|
||||
once; WebKit transfers it twice despite HTTP-cache reuse attempts. Cache sharing
|
||||
remains unresolved. Cold boot: 11,155/4,327 ms versus 10,480/3,290; warm:
|
||||
671/121 versus 692/139; offline: 264/133 versus 259/137. Single-run cold regressions
|
||||
need further investigation; no claim that every performance target was met.
|
||||
|
||||
Owner iPhone checks: locked playback, override/cancel, stall recovery, offline
|
||||
launch and OPFS/quota coexistence. No push, merge or deployment.
|
||||
Reference in New Issue
Block a user