Merge Phase 6 and reconcile offline completion, response capture and contract tests

This commit is contained in:
Jonathan Sykes
2026-10-09 15:12:14 +08:00
62 changed files with 229652 additions and 43 deletions

View File

@@ -347,3 +347,25 @@ node --test frontend/media-icons.test.js
Both harnesses run Chromium and WebKit at mobile dimensions with stubbed SpeechRecognition and local Saved/Queue metadata. They serve only the frontend, block service workers and external requests, and never download media. Geometry tests cold and switched layouts, six widths (320–430), mic visible/hidden and update icon visible/hidden: center spread ≤1px, touch targets ≥40px, Saved image/text gap ≥8px, no horizontal overflow or clipped car control. `--quick` limits widths and speech cases; `--browser` selects an engine; `--frontend` selects historical fixtures. `--measure-only --label before` records known broken geometry without exiting nonzero.
Icon checks switch the same page through four layouts × dark/light/contrast, assert SVG definitions, inherited colour, stroke family and save/progress/offline state, and save Queue/Now Playing/navigation shots. Glass Stage intentionally hides bottom navigation, so its full page is recorded instead. Any assertion failure exits nonzero. Shots and raw measurements live in git-ignored plans/ui-shots/. Full production inventory: plans/ui-icon-inventory.md. Native speech recognition, installed-PWA safe-area insets and iPhone rendering still need device verification.
### Cold waterfall diagnosis
`--source-root perf/.tmp/<historical-worktree>` runs that worktree's matching
frontend **and server**; `--frontend-commit` instead combines archived frontend
with the current backend. Run historical comparisons sequentially to avoid CPU
contention. The result records `sourceCommit`, `sourceRoot` and the served build.
Every cold sample has `waterfalls`: proxy request order/start/headers/end times
and page Resource Timing discovery/start/end times. Proxy times start when
tracking begins; page times start at navigation. Compare within each clock,
then use the page FCP to locate the rendering dependency.
Pass `--assert-cold` on new builds to require exactly one positive-byte app.js
response in every cold sample, including worker installation. Omit this assertion
when diagnosing historical regressions.
Phase 6 counts its fetch-owned app.js response in initial JS/CSS bytes. Since the
bootstrap consumes that response asynchronously, DOMContentLoaded no longer means
app execution is complete; compare the existing actual boot-done landmark.
`--scenario warm,offline,update-js,update-css,update-feature` runs a regression
sweep without repeating an already-completed cold acceptance run.

View File

@@ -26,7 +26,7 @@
*/
import assert from 'node:assert/strict';
import { assertChangedAssets, assertWarmAssets, waitForIdleAssets } from './measurement.mjs';
import { assertColdAssets, assertChangedAssets, assertWarmAssets, waitForIdleAssets } from './measurement.mjs';
import { createHash } from 'node:crypto';
import { spawn, spawnSync, execFileSync } from 'node:child_process';
import { existsSync, mkdirSync, rmSync, cpSync, appendFileSync, statSync, writeFileSync, readFileSync, symlinkSync, unlinkSync } from 'node:fs';
@@ -62,6 +62,8 @@ function parseArgs() {
out: null,
compare: null,
frontendCommit: null,
sourceRoot: null,
assertCold: false,
};
for (let i = 0; i < args.length; i++) {
@@ -71,6 +73,8 @@ function parseArgs() {
else if (a === '--profile' && i + 1 < args.length) options.profile = args[++i];
else if (a === '--scenario' && i + 1 < args.length) options.scenario = args[++i];
else if (a === '--out' && i + 1 < args.length) options.out = args[++i];
else if (a === '--assert-cold') options.assertCold = true;
else if (a === '--source-root' && i + 1 < args.length) options.sourceRoot = path.resolve(args[++i]);
else if (a === '--frontend-commit' && i + 1 < args.length) options.frontendCommit = args[++i];
else if (a === '--compare' && i + 1 < args.length) options.compare = args[++i];
}
@@ -151,7 +155,8 @@ async function seedDatabase(dbPath, mediaFiles) {
* Bun Server Manager
*/
class ServerManager {
constructor(scratchDir, publicDir) {
constructor(scratchDir, publicDir, sourceRoot = REPO_ROOT) {
this.sourceRoot = sourceRoot;
this.scratchDir = scratchDir;
this.publicDir = publicDir;
this.dataDir = path.join(scratchDir, 'data');
@@ -184,7 +189,7 @@ class ServerManager {
DB_PATH: this.dbPath,
};
const serverScript = path.join(REPO_ROOT, 'server', 'server.js');
const serverScript = path.join(this.sourceRoot, 'server', 'server.js');
this.serverProcess = spawn('bun', [serverScript], {
cwd: srvCwd,
env,
@@ -372,8 +377,8 @@ async function runColdScenario({ browserType, server, proxy, profile }) {
const fcp = paint.find((p) => p.name === 'first-contentful-paint');
return {
initialJsCss: performance.getEntriesByType('resource').filter(entry=>/\.(?:js|css)(?:[?#]|$)/.test(entry.name)&&entry.startTime <= nav.domContentLoadedEventEnd&&['script','link','css'].includes(entry.initiatorType)).reduce((sum,entry)=>sum+entry.encodedBodySize,0),
initialAssetRequests: performance.getEntriesByType('resource').filter(entry=>/\.(?:js|css)(?:[?#]|$)/.test(entry.name)&&entry.startTime <= nav.domContentLoadedEventEnd&&['script','link','css'].includes(entry.initiatorType)).map(entry=>({url:entry.name,bytes:entry.encodedBodySize})),
initialJsCss: performance.getEntriesByType('resource').filter(entry=>/\.(?:js|css)(?:[?#]|$)/.test(entry.name)&&entry.startTime <= nav.domContentLoadedEventEnd&&(['script','link','css'].includes(entry.initiatorType)||(entry.initiatorType==='fetch'&&new URL(entry.name).pathname==='/app.js'))).reduce((sum,entry)=>sum+entry.encodedBodySize,0),
initialAssetRequests: performance.getEntriesByType('resource').filter(entry=>/\.(?:js|css)(?:[?#]|$)/.test(entry.name)&&entry.startTime <= nav.domContentLoadedEventEnd&&(['script','link','css'].includes(entry.initiatorType)||(entry.initiatorType==='fetch'&&new URL(entry.name).pathname==='/app.js'))).map(entry=>({url:entry.name,bytes:entry.encodedBodySize,start:entry.startTime,responseStart:entry.responseStart,end:entry.responseEnd,initiator:entry.initiatorType})),
fcp: fcp ? Math.round(fcp.startTime) : null,
lcp: window.__lcp ? Math.round(window.__lcp) : null,
domContentLoaded: nav ? Math.round(nav.domContentLoadedEventEnd - nav.startTime) : null,
@@ -481,8 +486,8 @@ async function runWarmScenario({ browserType, server, proxy, profile }) {
const fcp = paint.find((p) => p.name === 'first-contentful-paint');
return {
initialJsCss: performance.getEntriesByType('resource').filter(entry=>/\.(?:js|css)(?:[?#]|$)/.test(entry.name)&&entry.startTime <= nav.domContentLoadedEventEnd&&['script','link','css'].includes(entry.initiatorType)).reduce((sum,entry)=>sum+entry.encodedBodySize,0),
initialAssetRequests: performance.getEntriesByType('resource').filter(entry=>/\.(?:js|css)(?:[?#]|$)/.test(entry.name)&&entry.startTime <= nav.domContentLoadedEventEnd&&['script','link','css'].includes(entry.initiatorType)).map(entry=>({url:entry.name,bytes:entry.encodedBodySize})),
initialJsCss: performance.getEntriesByType('resource').filter(entry=>/\.(?:js|css)(?:[?#]|$)/.test(entry.name)&&entry.startTime <= nav.domContentLoadedEventEnd&&(['script','link','css'].includes(entry.initiatorType)||(entry.initiatorType==='fetch'&&new URL(entry.name).pathname==='/app.js'))).reduce((sum,entry)=>sum+entry.encodedBodySize,0),
initialAssetRequests: performance.getEntriesByType('resource').filter(entry=>/\.(?:js|css)(?:[?#]|$)/.test(entry.name)&&entry.startTime <= nav.domContentLoadedEventEnd&&(['script','link','css'].includes(entry.initiatorType)||(entry.initiatorType==='fetch'&&new URL(entry.name).pathname==='/app.js'))).map(entry=>({url:entry.name,bytes:entry.encodedBodySize,start:entry.startTime,responseStart:entry.responseStart,end:entry.responseEnd,initiator:entry.initiatorType})),
fcp: fcp ? Math.round(fcp.startTime) : null,
lcp: window.__lcp ? Math.round(window.__lcp) : null,
domContentLoaded: nav ? Math.round(nav.domContentLoadedEventEnd - nav.startTime) : null,
@@ -562,8 +567,8 @@ async function runOfflineScenario({ browserType, server, proxy, profile }) {
const fcp = paint.find((p) => p.name === 'first-contentful-paint');
return {
initialJsCss: performance.getEntriesByType('resource').filter(entry=>/\.(?:js|css)(?:[?#]|$)/.test(entry.name)&&entry.startTime <= nav.domContentLoadedEventEnd&&['script','link','css'].includes(entry.initiatorType)).reduce((sum,entry)=>sum+entry.encodedBodySize,0),
initialAssetRequests: performance.getEntriesByType('resource').filter(entry=>/\.(?:js|css)(?:[?#]|$)/.test(entry.name)&&entry.startTime <= nav.domContentLoadedEventEnd&&['script','link','css'].includes(entry.initiatorType)).map(entry=>({url:entry.name,bytes:entry.encodedBodySize})),
initialJsCss: performance.getEntriesByType('resource').filter(entry=>/\.(?:js|css)(?:[?#]|$)/.test(entry.name)&&entry.startTime <= nav.domContentLoadedEventEnd&&(['script','link','css'].includes(entry.initiatorType)||(entry.initiatorType==='fetch'&&new URL(entry.name).pathname==='/app.js'))).reduce((sum,entry)=>sum+entry.encodedBodySize,0),
initialAssetRequests: performance.getEntriesByType('resource').filter(entry=>/\.(?:js|css)(?:[?#]|$)/.test(entry.name)&&entry.startTime <= nav.domContentLoadedEventEnd&&(['script','link','css'].includes(entry.initiatorType)||(entry.initiatorType==='fetch'&&new URL(entry.name).pathname==='/app.js'))).map(entry=>({url:entry.name,bytes:entry.encodedBodySize,start:entry.startTime,responseStart:entry.responseStart,end:entry.responseEnd,initiator:entry.initiatorType})),
fcp: fcp ? Math.round(fcp.startTime) : null,
lcp: window.__lcp ? Math.round(window.__lcp) : null,
domContentLoaded: nav ? Math.round(nav.domContentLoadedEventEnd - nav.startTime) : null,
@@ -704,6 +709,8 @@ async function main() {
if (options.browser === 'all' || options.browser === 'chromium') browsers.push(pw.chromium);
if (options.browser === 'all' || options.browser === 'webkit') browsers.push(pw.webkit);
const requestedScenarios=new Set(options.scenario.split(','));
const wants=name=>requestedScenarios.has('all')||requestedScenarios.has(name);
const profiles = [];
if (options.profile === 'all' || options.profile === 'lte') profiles.push('lte');
if (options.profile === 'all' || options.profile === 'lossy') profiles.push('lossy');
@@ -717,7 +724,7 @@ async function main() {
const treeUpdateCss = path.join(tmpRoot, 'tree-update-css');
const treeUpdateFeature = path.join(tmpRoot, 'tree-update-feature');
let frontendSource=path.join(REPO_ROOT,'frontend');
let frontendSource=path.join(options.sourceRoot || REPO_ROOT,'frontend');
if(options.frontendCommit) {
const archive=path.join(tmpRoot,'frontend.tar');
writeFileSync(archive,execFileSync('git',['archive',options.frontendCommit,'frontend'],{cwd:REPO_ROOT,maxBuffer:20*1024*1024}));
@@ -735,13 +742,15 @@ async function main() {
const trees = { treeBase, treeUpdateJs, treeUpdateCss, treeUpdateFeature };
const serverScratch = path.join(tmpRoot, 'server-run');
const server = new ServerManager(serverScratch, treeBase);
const server = new ServerManager(serverScratch, treeBase, options.sourceRoot || REPO_ROOT);
await server.start();
console.log(`Bun server running on ephemeral port ${server.port}`);
const results = {
date: new Date().toISOString(),
frontendCommit: options.frontendCommit,
sourceRoot: options.sourceRoot,
sourceCommit: spawnSync('git', ['rev-parse','HEAD'], { cwd: options.sourceRoot || REPO_ROOT }).stdout.toString().trim(),
frontendBuildTag: (await (await fetch('http://127.0.0.1:'+server.port+'/api/version')).json()).buildTag,
commit: spawnSync('git', ['rev-parse', 'HEAD'], { cwd: REPO_ROOT }).stdout.toString().trim(),
runsConfigured: options.runs,
@@ -754,6 +763,9 @@ async function main() {
results.browsers[bName] = {};
for (const prof of profiles) {
// The preceding profile can end on a synthetic feature-update tree.
// Always measure the actual base build on the next cold visit.
await server.restartWithPublic(treeBase);
console.log(`\n>>> Running Benchmark: Browser=[${bName}] Profile=[${prof}]`);
results.browsers[bName][prof] = {};
@@ -763,14 +775,15 @@ async function main() {
console.log(`Proxy listening on port ${proxy.port} (mode: ${proxyProfile})`);
// 1. Cold Scenario
if (options.scenario === 'all' || options.scenario === 'cold') {
if (wants('cold')) {
console.log(` [Scenario: Cold Load] running ${options.runs} iterations...`);
const coldRuns = [];
for (let r = 0; r < options.runs; r++) {
process.stdout.write(` run ${r + 1}/${options.runs}... `);
const res = await runColdScenario({ browserType: bType, server, proxy, profile: prof });
if(options.assertCold)assertColdAssets(res.requests);
coldRuns.push(res);
console.log(`done (${res.wireBytes} bytes, ${res.requestCount} reqs, boot=${res.bootDone}ms)`);
console.log(`done (${res.wireBytes} bytes, ${res.requestCount} reqs, fcp=${res.fcp}ms, boot=${res.bootDone}ms)`);
}
results.browsers[bName][prof].cold = {
@@ -791,11 +804,12 @@ async function main() {
requests: coldRuns[0]?.requests || [],
initialJsCss: summarizeList(coldRuns.map(r=>r.initialJsCss)),
initialAssetRequests: coldRuns[0]?.initialAssetRequests || [],
waterfalls: coldRuns.map(r=>({fcp:r.fcp,requests:r.requests,page:r.initialAssetRequests})),
};
}
// 2. Warm Scenario
if (options.scenario === 'all' || options.scenario === 'warm') {
if (wants('warm')) {
console.log(` [Scenario: Warm Load] running ${options.runs} iterations...`);
const warmRuns = [];
for (let r = 0; r < options.runs; r++) {
@@ -817,7 +831,7 @@ async function main() {
}
// 3. Offline Scenario
if (options.scenario === 'all' || options.scenario === 'offline') {
if (wants('offline')) {
console.log(` [Scenario: Offline Reload] running ${options.runs} iterations...`);
const offRuns = [];
for (let r = 0; r < options.runs; r++) {
@@ -839,7 +853,7 @@ async function main() {
}
// 4. Update N -> N+1 (JS)
if (options.scenario === 'all' || options.scenario === 'update-js') {
if (wants('update-js')) {
console.log(` [Scenario: Update N->N+1 (1-line app.js)] running ${options.runs} iterations...`);
const updJsRuns = [];
for (let r = 0; r < options.runs; r++) {
@@ -866,7 +880,7 @@ async function main() {
}
// 5. Update N -> N+1 (CSS)
if (options.scenario === 'all' || options.scenario === 'update-css') {
if (wants('update-css')) {
console.log(` [Scenario: Update N->N+1 (1-line theme-glass.css)] running ${options.runs} iterations...`);
const updCssRuns = [];
for (let r = 0; r < options.runs; r++) {
@@ -894,7 +908,7 @@ async function main() {
};
}
if ((options.scenario === 'all' || options.scenario === 'update-feature') && existsSync(path.join(treeBase,'presenter.js'))) {
if ((wants('update-feature')) && existsSync(path.join(treeBase,'presenter.js'))) {
console.log(` [Scenario: Update split-out presenter, including idle cache fill] running ${options.runs} iterations...`);
const runs=[];
for(let r=0;r<options.runs;r++) {

View File

@@ -84,6 +84,23 @@ async function run(name){
await page.evaluate(async()=>{await Lazy.load('feature:export');await Lazy.load('feature:video-edit');});
assert.equal(proxy.getStats().requestCount,before,'all warmed extension assets stay offline');
await start();disconnected=false;await proxy.setOffline(false);await page.evaluate(()=>localStorage.removeItem('perf-offline'));
// Change only app bytes, then prove loss of its current cache entry can boot
// the compatible N-1 core offline without weakening the inline CSP policy.
await stop();writeFileSync(join(cwd,'public/app.js'),readFileSync(join(cwd,'public/app.js'),'utf8')+'\n// phase6 app eviction probe\n');await start();
const appTarget=await(await fetch(origin+'/api/manifest')).json();
await page.evaluate(async()=>{const r=await navigator.serviceWorker.getRegistration();await r.update();});
await wait(page,async tag=>{const r=await navigator.serviceWorker.getRegistration();return r?.waiting&&(await SwUpdate.askCacheStatus(r.waiting))?.version===tag;},appTarget.buildTag);
await page.evaluate(async()=>{const r=await navigator.serviceWorker.getRegistration();r.waiting.postMessage({type:'SKIP_WAITING'});});
await wait(page,async tag=>{const c=await caches.open('ytplayer-assets');return(await(await c.match('/__ytp_asset_state')).json()).current.buildTag===tag;},appTarget.buildTag);
const appKey='/app.js?v='+appTarget.files['/app.js'].h;
await page.evaluate(async key=>{await(await caches.open('ytplayer-assets')).delete(key);},appKey);
await stop();disconnected=true;await proxy.setOffline(true);
const probe=await context.newPage();probe.on('pageerror',e=>errors.push({message:e.message,disconnected}));
const offlineBefore=proxy.getStats().requestCount;await probe.goto(origin);await probe.waitForFunction(()=>typeof data!=='undefined'&&typeof Player!=='undefined'&&document.querySelector('#carModeBtn'));
assert.equal(await probe.evaluate(async key=>!!await(await caches.open('ytplayer-assets')).match(key),appKey),false,'N-1 never poisons the current app key');
assert.equal(proxy.getStats().requestCount,offlineBefore,'N-1 app boot is entirely offline');
await probe.close();await start();disconnected=false;await proxy.setOffline(false);
await page.evaluate(async key=>{const r=await fetch(key+'&__ytpfresh=1');if(r.headers.get('X-Asset-Hash')!==key.split('v=')[1])throw Error('Wrong repair body');await(await caches.open('ytplayer-assets')).put(key,r);},appKey);
// Keep an old tab whose core and group contracts remain those of build N.
const old=await context.newPage();old.on('pageerror',e=>errors.push({message:e.message,disconnected}));await old.goto(origin);await old.waitForSelector('#carModeBtn');
await old.evaluate(async()=>{window.__saveData=true;await Lazy.load('feature:setlist-import');window.__pinned=window.SetlistImport;});
@@ -133,7 +150,7 @@ async function run(name){
const offlineTransportErrors=errors.filter(error=>name==='webkit'&&error.disconnected&&(error.message==='TypeError: Load failed'||/\/api\/(?:recommendations\?[^\s]*|version)\.$/.test(error.message)));
assert.deepEqual(errors.filter(error=>!offlineTransportErrors.includes(error)),[]);
if(offlineTransportErrors.length)assert.ok(failedRequests.some(url=>/\/api\/(?:recommendations|version)/.test(url)));
results.push({browser:name,sourceBuildTag:previous.buildTag,classicSharedDefaults:true,cssOrderPreserved:true,settingsSearch:true,carControls:4,offlineFeature:true,firstUseNetwork:0,layoutsOffline:['glass-stage','bento-hub','f7-swipe','classic'],pinned:true,compatibleUnexecutedNewURL:true,incompatibleN1ReloadRequired:true,stagedN1:true,playbackGuard:true,prePaintLayout:true,offlineSettingsPanels:true,scriptErrors:[],offlineTransportErrors});
results.push({browser:name,sourceBuildTag:previous.buildTag,classicSharedDefaults:true,cssOrderPreserved:true,settingsSearch:true,carControls:4,offlineFeature:true,firstUseNetwork:0,layoutsOffline:['glass-stage','bento-hub','f7-swipe','classic'],pinned:true,compatibleUnexecutedNewURL:true,incompatibleN1ReloadRequired:true,stagedN1:true,appEvictionN1Offline:true,playbackGuard:true,prePaintLayout:true,offlineSettingsPanels:true,scriptErrors:[],offlineTransportErrors});
console.log(name,'PASS');
} catch(error){console.error(name,error.stack);throw error;} finally {await browser?.close();proxy?.server.closeAllConnections();await proxy?.close();await stop();}
}

View File

@@ -27,3 +27,8 @@ export function assertWarmAssets(requests) {
const assets=requests.filter(r=>r.bytes>0&&/\.(?:js|css|woff2?|png|svg)(?:[?#]|$)/.test(r.url)&&!new URL(r.url,'http://localhost').pathname.endsWith('/sw.js'));
assert.deepEqual(assets,[],'warm reload does not transfer unfinished shell assets');
}
export function assertColdAssets(requests) {
const transferred=requests.filter(r=>r.bytes>0&&new URL(r.url,'http://localhost').pathname==='/app.js');
assert.equal(transferred.length,1,'cold app.js transfers its body exactly once across page and worker');
}

View File

@@ -1,6 +1,6 @@
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { assertChangedAssets, assertWarmAssets } from './measurement.mjs';
import { assertChangedAssets, assertWarmAssets, assertColdAssets } from './measurement.mjs';
test('changed CSS and feature measurements reject unrelated application transfers',()=>{
const requests=[{url:'/sw.js',bytes:7000},{url:'/asset-sync-core.js',bytes:2000},{url:'/index.html',bytes:12000},{url:'/api/manifest',bytes:3000},{url:'/theme-glass.css?v=new',bytes:5000},{url:'/fonts/a.woff2',bytes:0}];
assertChangedAssets(requests,'/theme-glass.css');
@@ -14,3 +14,10 @@ test('warm measurements reject unfinished shell downloads but allow API checks',
assertWarmAssets([{url:'/api/version',bytes:62},{url:'/app.js?v=current',bytes:0}]);
assert.throws(()=>assertWarmAssets([{url:'/theme-glass.css?v=current',bytes:5000}]));
});
test('cold acceptance rejects a second positive app response while allowing cache revalidation',()=>{
assertColdAssets([{url:'/app.js?v=current',bytes:12000},{url:'/app.js?v=current',bytes:0}]);
assert.throws(()=>assertColdAssets([{url:'/app.js?v=current',bytes:12000},{url:'/app.js?v=current',bytes:12000}]));
assert.throws(()=>assertColdAssets([]));
});

View File

@@ -47,6 +47,7 @@ export function categorizeContentType(contentType, urlPath) {
*/
export function createThrottleProxy({ targetPort, profile = 'lte' }) {
let activeTracking = false;
let trackingStart = 0;
let requestCount = 0;
let requests = [];
let totalWireBytes = 0;
@@ -79,6 +80,7 @@ export function createThrottleProxy({ targetPort, profile = 'lte' }) {
return;
}
const requestStart = Date.now();
reqIndex++;
const currentReqIndex = reqIndex;
@@ -114,7 +116,8 @@ export function createThrottleProxy({ targetPort, profile = 'lte' }) {
let recorded;
if (activeTracking) {
requestCount++;
recorded={url:clientReq.url,status:upRes.statusCode,bytes:0};
recorded={url:clientReq.url,status:upRes.statusCode,bytes:0,index:currentReqIndex,startMs:requestStart-trackingStart,headersMs:Date.now()-trackingStart};
clientRes.once('finish',()=>{recorded.endMs=Date.now()-trackingStart;});
requests.push(recorded);
}
@@ -176,6 +179,7 @@ export function createThrottleProxy({ targetPort, profile = 'lte' }) {
server.close(resolve);
}),
startTracking: () => {
trackingStart = Date.now();
activeTracking = true;
},
stopTracking: () => {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,135 @@
{
"date": "2026-10-08T04:01:24.068Z",
"frontendCommit": null,
"sourceRoot": null,
"sourceCommit": "4b1f5204f8fcd207305ee50fff29985497e58e3b",
"frontendBuildTag": "bb9fea44045d",
"commit": "4b1f5204f8fcd207305ee50fff29985497e58e3b",
"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": 40,
"min": 40,
"max": 40,
"values": [
40
]
},
"lcp": {
"median": 40,
"min": 40,
"max": 40,
"values": [
40
]
},
"domContentLoaded": {
"median": 147,
"min": 147,
"max": 147,
"values": [
147
]
},
"bootDone": {
"median": 152,
"min": 152,
"max": 152,
"values": [
152
]
},
"reloadDuration": {
"median": 169,
"min": 169,
"max": 169,
"values": [
169
]
}
}
}
},
"webkit": {
"lte": {
"offline": {
"requestCount": {
"median": 0,
"min": 0,
"max": 0,
"values": [
0
]
},
"wireBytes": {
"median": 0,
"min": 0,
"max": 0,
"values": [
0
]
},
"fcp": {
"median": 63,
"min": 63,
"max": 63,
"values": [
63
]
},
"lcp": {
"median": 97,
"min": 97,
"max": 97,
"values": [
97
]
},
"domContentLoaded": {
"median": 93,
"min": 93,
"max": 93,
"values": [
93
]
},
"bootDone": {
"median": 99,
"min": 99,
"max": 99,
"values": [
99
]
},
"reloadDuration": {
"median": 118,
"min": 118,
"max": 118,
"values": [
118
]
}
}
}
}
}
}

View File

@@ -0,0 +1,135 @@
{
"date": "2026-10-09T01:16:09.809Z",
"frontendCommit": null,
"sourceRoot": null,
"sourceCommit": "71608c2ce81207ca21c8adbc49edbc2893f5170e",
"frontendBuildTag": "bb9fea44045d",
"commit": "71608c2ce81207ca21c8adbc49edbc2893f5170e",
"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": 108,
"min": 108,
"max": 108,
"values": [
108
]
},
"lcp": {
"median": 108,
"min": 108,
"max": 108,
"values": [
108
]
},
"domContentLoaded": {
"median": 345,
"min": 345,
"max": 345,
"values": [
345
]
},
"bootDone": {
"median": 353,
"min": 353,
"max": 353,
"values": [
353
]
},
"reloadDuration": {
"median": 401,
"min": 401,
"max": 401,
"values": [
401
]
}
}
}
},
"webkit": {
"lte": {
"offline": {
"requestCount": {
"median": 0,
"min": 0,
"max": 0,
"values": [
0
]
},
"wireBytes": {
"median": 0,
"min": 0,
"max": 0,
"values": [
0
]
},
"fcp": {
"median": 127,
"min": 127,
"max": 127,
"values": [
127
]
},
"lcp": {
"median": 184,
"min": 184,
"max": 184,
"values": [
184
]
},
"domContentLoaded": {
"median": 180,
"min": 180,
"max": 180,
"values": [
180
]
},
"bootDone": {
"median": 187,
"min": 187,
"max": 187,
"values": [
187
]
},
"reloadDuration": {
"median": 213,
"min": 213,
"max": 213,
"values": [
213
]
}
}
}
}
}
}

View File

@@ -0,0 +1,97 @@
{
"results": [
{
"browser": "chromium",
"sourceBuildTag": "31617662d2f0",
"classicSharedDefaults": true,
"cssOrderPreserved": true,
"settingsSearch": true,
"carControls": 4,
"offlineFeature": true,
"firstUseNetwork": 0,
"layoutsOffline": [
"glass-stage",
"bento-hub",
"f7-swipe",
"classic"
],
"pinned": true,
"compatibleUnexecutedNewURL": true,
"incompatibleN1ReloadRequired": true,
"stagedN1": true,
"appEvictionN1Offline": true,
"playbackGuard": true,
"prePaintLayout": true,
"offlineSettingsPanels": true,
"scriptErrors": [],
"offlineTransportErrors": []
},
{
"browser": "webkit",
"sourceBuildTag": "31617662d2f0",
"classicSharedDefaults": true,
"cssOrderPreserved": true,
"settingsSearch": true,
"carControls": 4,
"offlineFeature": true,
"firstUseNetwork": 0,
"layoutsOffline": [
"glass-stage",
"bento-hub",
"f7-swipe",
"classic"
],
"pinned": true,
"compatibleUnexecutedNewURL": true,
"incompatibleN1ReloadRequired": true,
"stagedN1": true,
"appEvictionN1Offline": true,
"playbackGuard": true,
"prePaintLayout": true,
"offlineSettingsPanels": true,
"scriptErrors": [],
"offlineTransportErrors": [
{
"message": "TypeError: Load failed",
"disconnected": true
},
{
"message": "/127.0.0.1:41337/api/version.",
"disconnected": true
},
{
"message": "TypeError: Load failed",
"disconnected": true
},
{
"message": "/127.0.0.1:41337/api/recommendations?fp=163577c02a53bc40.",
"disconnected": true
},
{
"message": "TypeError: Load failed",
"disconnected": true
},
{
"message": "/127.0.0.1:41337/api/version.",
"disconnected": true
},
{
"message": "TypeError: Load failed",
"disconnected": true
},
{
"message": "/127.0.0.1:41337/api/recommendations?fp=163577c02a53bc40.",
"disconnected": true
},
{
"message": "TypeError: Load failed",
"disconnected": true
},
{
"message": "/127.0.0.1:41337/api/version.",
"disconnected": true
}
]
}
]
}

View File

@@ -0,0 +1,97 @@
{
"results": [
{
"browser": "chromium",
"sourceBuildTag": "31617662d2f0",
"classicSharedDefaults": true,
"cssOrderPreserved": true,
"settingsSearch": true,
"carControls": 4,
"offlineFeature": true,
"firstUseNetwork": 0,
"layoutsOffline": [
"glass-stage",
"bento-hub",
"f7-swipe",
"classic"
],
"pinned": true,
"compatibleUnexecutedNewURL": true,
"incompatibleN1ReloadRequired": true,
"stagedN1": true,
"appEvictionN1Offline": true,
"playbackGuard": true,
"prePaintLayout": true,
"offlineSettingsPanels": true,
"scriptErrors": [],
"offlineTransportErrors": []
},
{
"browser": "webkit",
"sourceBuildTag": "31617662d2f0",
"classicSharedDefaults": true,
"cssOrderPreserved": true,
"settingsSearch": true,
"carControls": 4,
"offlineFeature": true,
"firstUseNetwork": 0,
"layoutsOffline": [
"glass-stage",
"bento-hub",
"f7-swipe",
"classic"
],
"pinned": true,
"compatibleUnexecutedNewURL": true,
"incompatibleN1ReloadRequired": true,
"stagedN1": true,
"appEvictionN1Offline": true,
"playbackGuard": true,
"prePaintLayout": true,
"offlineSettingsPanels": true,
"scriptErrors": [],
"offlineTransportErrors": [
{
"message": "TypeError: Load failed",
"disconnected": true
},
{
"message": "/127.0.0.1:38297/api/version.",
"disconnected": true
},
{
"message": "TypeError: Load failed",
"disconnected": true
},
{
"message": "/127.0.0.1:38297/api/recommendations?fp=163577c02a53bc40.",
"disconnected": true
},
{
"message": "TypeError: Load failed",
"disconnected": true
},
{
"message": "/127.0.0.1:38297/api/version.",
"disconnected": true
},
{
"message": "TypeError: Load failed",
"disconnected": true
},
{
"message": "/127.0.0.1:38297/api/recommendations?fp=163577c02a53bc40.",
"disconnected": true
},
{
"message": "TypeError: Load failed",
"disconnected": true
},
{
"message": "/127.0.0.1:38297/api/version.",
"disconnected": true
}
]
}
]
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,191 @@
{
"date": "2026-10-08T03:15:23.029Z",
"frontendCommit": null,
"sourceRoot": "/home/josh/development/personal/ytplayer-codex/wt-assets/perf/.tmp/phase6-merged-bootstrap",
"sourceCommit": "9408ee07e56db5bbb8319f8da862b549ab948bce",
"frontendBuildTag": "c4bb42682ab8",
"commit": "9408ee07e56db5bbb8319f8da862b549ab948bce",
"runsConfigured": 5,
"browsers": {
"chromium": {
"lte": {
"warm": {
"requestCount": {
"median": 4,
"min": 3,
"max": 5,
"values": [
4,
4,
5,
4,
3
]
},
"wireBytes": {
"median": 7990,
"min": 7979,
"max": 7990,
"values": [
7990,
7990,
7990,
7990,
7979
]
},
"fcp": {
"median": 136,
"min": 108,
"max": 144,
"values": [
140,
116,
136,
108,
144
]
},
"lcp": {
"median": 148,
"min": 136,
"max": 168,
"values": [
168,
148,
136,
156,
144
]
},
"domContentLoaded": {
"median": 409,
"min": 382,
"max": 418,
"values": [
409,
382,
418,
412,
402
]
},
"bootDone": {
"median": 425,
"min": 398,
"max": 433,
"values": [
425,
398,
433,
430,
417
]
},
"longTaskTotal": {
"median": 63,
"min": 56,
"max": 65,
"values": [
63,
65,
63,
57,
56
]
}
}
}
},
"webkit": {
"lte": {
"warm": {
"requestCount": {
"median": 0,
"min": 0,
"max": 0,
"values": [
0,
0,
0,
0,
0
]
},
"wireBytes": {
"median": 0,
"min": 0,
"max": 0,
"values": [
0,
0,
0,
0,
0
]
},
"fcp": {
"median": 92,
"min": 79,
"max": 94,
"values": [
92,
92,
87,
94,
79
]
},
"lcp": {
"median": 92,
"min": 79,
"max": 94,
"values": [
92,
92,
87,
94,
79
]
},
"domContentLoaded": {
"median": 89,
"min": 77,
"max": 92,
"values": [
89,
90,
84,
92,
77
]
},
"bootDone": {
"median": 95,
"min": 83,
"max": 98,
"values": [
95,
96,
91,
98,
83
]
},
"longTaskTotal": {
"median": 0,
"min": 0,
"max": 0,
"values": [
0,
0,
0,
0,
0
]
}
}
}
}
}
}

View File

@@ -0,0 +1,41 @@
{
"commit": "b77938a",
"results": [
{
"browser": "chromium",
"oldTag": "1175f1a1d2c1",
"newTag": "31617662d2f0",
"banners": 1,
"updateReloads": 1,
"cachedFiles": 122,
"durationMs": 25233,
"wireBytes": 631091,
"offline": true,
"legacyURLs": 21,
"profile": "lossy",
"userInitiatedOnly": true,
"playbackGuard": true,
"evictionRepair": true,
"incrementalRefresh": true,
"offlineTransportErrors": 0
},
{
"browser": "webkit",
"oldTag": "1175f1a1d2c1",
"newTag": "31617662d2f0",
"banners": 1,
"updateReloads": 1,
"cachedFiles": 122,
"durationMs": 22860,
"wireBytes": 741571,
"offline": true,
"legacyURLs": 21,
"profile": "lossy",
"userInitiatedOnly": true,
"playbackGuard": true,
"evictionRepair": true,
"incrementalRefresh": true,
"offlineTransportErrors": 4
}
]
}

View File

@@ -0,0 +1,41 @@
{
"commit": "b77938a",
"results": [
{
"browser": "chromium",
"oldTag": "1175f1a1d2c1",
"newTag": "31617662d2f0",
"banners": 1,
"updateReloads": 1,
"cachedFiles": 122,
"durationMs": 27355,
"wireBytes": 631091,
"offline": true,
"legacyURLs": 21,
"profile": "lossy",
"userInitiatedOnly": true,
"playbackGuard": true,
"evictionRepair": true,
"incrementalRefresh": true,
"offlineTransportErrors": 0
},
{
"browser": "webkit",
"oldTag": "1175f1a1d2c1",
"newTag": "31617662d2f0",
"banners": 1,
"updateReloads": 1,
"cachedFiles": 122,
"durationMs": 24426,
"wireBytes": 730395,
"offline": true,
"legacyURLs": 21,
"profile": "lossy",
"userInitiatedOnly": true,
"playbackGuard": true,
"evictionRepair": true,
"incrementalRefresh": true,
"offlineTransportErrors": 4
}
]
}

View File

@@ -0,0 +1,41 @@
{
"commit": "b77938a",
"results": [
{
"browser": "chromium",
"oldTag": "1175f1a1d2c1",
"newTag": "31617662d2f0",
"banners": 1,
"updateReloads": 1,
"cachedFiles": 122,
"durationMs": 9809,
"wireBytes": 640960,
"offline": true,
"legacyURLs": 21,
"profile": "unthrottled",
"userInitiatedOnly": true,
"playbackGuard": true,
"evictionRepair": true,
"incrementalRefresh": true,
"offlineTransportErrors": 0
},
{
"browser": "webkit",
"oldTag": "1175f1a1d2c1",
"newTag": "31617662d2f0",
"banners": 1,
"updateReloads": 1,
"cachedFiles": 122,
"durationMs": 9902,
"wireBytes": 755652,
"offline": true,
"legacyURLs": 21,
"profile": "unthrottled",
"userInitiatedOnly": true,
"playbackGuard": true,
"evictionRepair": true,
"incrementalRefresh": true,
"offlineTransportErrors": 4
}
]
}

View File

@@ -0,0 +1,41 @@
{
"commit": "b77938a",
"results": [
{
"browser": "chromium",
"oldTag": "1175f1a1d2c1",
"newTag": "31617662d2f0",
"banners": 1,
"updateReloads": 1,
"cachedFiles": 122,
"durationMs": 13290,
"wireBytes": 640960,
"offline": true,
"legacyURLs": 21,
"profile": "unthrottled",
"userInitiatedOnly": true,
"playbackGuard": true,
"evictionRepair": true,
"incrementalRefresh": true,
"offlineTransportErrors": 0
},
{
"browser": "webkit",
"oldTag": "1175f1a1d2c1",
"newTag": "31617662d2f0",
"banners": 1,
"updateReloads": 1,
"cachedFiles": 122,
"durationMs": 11711,
"wireBytes": 766828,
"offline": true,
"legacyURLs": 21,
"profile": "unthrottled",
"userInitiatedOnly": true,
"playbackGuard": true,
"evictionRepair": true,
"incrementalRefresh": true,
"offlineTransportErrors": 4
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,191 @@
{
"date": "2026-10-08T03:05:33.492Z",
"frontendCommit": null,
"sourceRoot": "/home/josh/development/personal/ytplayer-codex/wt-assets/perf/.tmp/phase6-native-cached",
"sourceCommit": "9408ee07e56db5bbb8319f8da862b549ab948bce",
"frontendBuildTag": "46ccefbb78f5",
"commit": "9408ee07e56db5bbb8319f8da862b549ab948bce",
"runsConfigured": 5,
"browsers": {
"chromium": {
"lte": {
"warm": {
"requestCount": {
"median": 4,
"min": 2,
"max": 4,
"values": [
4,
4,
2,
3,
4
]
},
"wireBytes": {
"median": 7996,
"min": 86,
"max": 7996,
"values": [
7996,
7996,
86,
7985,
7996
]
},
"fcp": {
"median": 124,
"min": 116,
"max": 132,
"values": [
128,
124,
116,
124,
132
]
},
"lcp": {
"median": 148,
"min": 148,
"max": 156,
"values": [
156,
148,
148,
148,
156
]
},
"domContentLoaded": {
"median": 432,
"min": 397,
"max": 464,
"values": [
464,
397,
432,
438,
413
]
},
"bootDone": {
"median": 448,
"min": 413,
"max": 482,
"values": [
482,
413,
448,
457,
430
]
},
"longTaskTotal": {
"median": 61,
"min": 58,
"max": 79,
"values": [
79,
58,
60,
70,
61
]
}
}
}
},
"webkit": {
"lte": {
"warm": {
"requestCount": {
"median": 0,
"min": 0,
"max": 0,
"values": [
0,
0,
0,
0,
0
]
},
"wireBytes": {
"median": 0,
"min": 0,
"max": 0,
"values": [
0,
0,
0,
0,
0
]
},
"fcp": {
"median": 65,
"min": 61,
"max": 66,
"values": [
66,
63,
65,
61,
65
]
},
"lcp": {
"median": 96,
"min": 92,
"max": 97,
"values": [
97,
96,
92,
93,
96
]
},
"domContentLoaded": {
"median": 93,
"min": 90,
"max": 94,
"values": [
94,
93,
90,
91,
93
]
},
"bootDone": {
"median": 98,
"min": 94,
"max": 98,
"values": [
98,
98,
94,
95,
98
]
},
"longTaskTotal": {
"median": 0,
"min": 0,
"max": 0,
"values": [
0,
0,
0,
0,
0
]
}
}
}
}
}
}

View File

@@ -0,0 +1,101 @@
{
"date": "2026-10-08T01:29:49.903Z",
"frontendCommit": null,
"sourceRoot": null,
"sourceCommit": "c4a512bea63da4c9c875501038727768080496c1",
"frontendBuildTag": "5fe61861d759",
"commit": "c4a512bea63da4c9c875501038727768080496c1",
"runsConfigured": 5,
"browsers": {
"chromium": {
"lte": {
"warm": {
"requestCount": {
"median": 4,
"min": 3,
"max": 5,
"values": [
5,
4,
3,
4,
3
]
},
"wireBytes": {
"median": 7869,
"min": 97,
"max": 7869,
"values": [
7869,
7869,
97,
7869,
7858
]
},
"fcp": {
"median": 140,
"min": 120,
"max": 152,
"values": [
152,
148,
120,
120,
140
]
},
"lcp": {
"median": 148,
"min": 140,
"max": 156,
"values": [
152,
148,
148,
156,
140
]
},
"domContentLoaded": {
"median": 398,
"min": 391,
"max": 406,
"values": [
404,
398,
396,
406,
391
]
},
"bootDone": {
"median": 414,
"min": 411,
"max": 420,
"values": [
418,
414,
411,
420,
412
]
},
"longTaskTotal": {
"median": 62,
"min": 57,
"max": 65,
"values": [
65,
59,
63,
57,
62
]
}
}
}
}
}
}

View File

@@ -0,0 +1,191 @@
{
"date": "2026-10-08T03:01:26.249Z",
"frontendCommit": null,
"sourceRoot": "/home/josh/development/personal/ytplayer-codex/wt-assets/perf/.tmp/phase6-native-parser",
"sourceCommit": "9408ee07e56db5bbb8319f8da862b549ab948bce",
"frontendBuildTag": "4ce3d20db0c7",
"commit": "9408ee07e56db5bbb8319f8da862b549ab948bce",
"runsConfigured": 5,
"browsers": {
"chromium": {
"lte": {
"warm": {
"requestCount": {
"median": 4,
"min": 3,
"max": 5,
"values": [
5,
4,
3,
4,
4
]
},
"wireBytes": {
"median": 8001,
"min": 7990,
"max": 8001,
"values": [
8001,
8001,
7990,
8001,
8001
]
},
"fcp": {
"median": 124,
"min": 120,
"max": 140,
"values": [
132,
124,
124,
140,
120
]
},
"lcp": {
"median": 156,
"min": 140,
"max": 160,
"values": [
160,
148,
156,
140,
160
]
},
"domContentLoaded": {
"median": 428,
"min": 405,
"max": 442,
"values": [
442,
428,
429,
405,
417
]
},
"bootDone": {
"median": 446,
"min": 422,
"max": 464,
"values": [
464,
446,
448,
422,
432
]
},
"longTaskTotal": {
"median": 65,
"min": 60,
"max": 79,
"values": [
79,
69,
65,
65,
60
]
}
}
}
},
"webkit": {
"lte": {
"warm": {
"requestCount": {
"median": 0,
"min": 0,
"max": 0,
"values": [
0,
0,
0,
0,
0
]
},
"wireBytes": {
"median": 0,
"min": 0,
"max": 0,
"values": [
0,
0,
0,
0,
0
]
},
"fcp": {
"median": 83,
"min": 81,
"max": 91,
"values": [
82,
91,
83,
88,
81
]
},
"lcp": {
"median": 83,
"min": 81,
"max": 91,
"values": [
82,
91,
83,
88,
81
]
},
"domContentLoaded": {
"median": 80,
"min": 79,
"max": 89,
"values": [
79,
89,
80,
86,
79
]
},
"bootDone": {
"median": 87,
"min": 86,
"max": 96,
"values": [
86,
96,
87,
93,
86
]
},
"longTaskTotal": {
"median": 0,
"min": 0,
"max": 0,
"values": [
0,
0,
0,
0,
0
]
}
}
}
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,28 @@
[
{
"browser": "chromium",
"checked": [
"shell",
"presenter",
"remote",
"party",
"share",
"stats"
],
"offlineNetworkRequests": 0,
"errors": []
},
{
"browser": "webkit",
"checked": [
"shell",
"presenter",
"remote",
"party",
"share",
"stats"
],
"offlineNetworkRequests": 0,
"errors": []
}
]

View File

@@ -0,0 +1,28 @@
[
{
"browser": "chromium",
"checked": [
"shell",
"presenter",
"remote",
"party",
"share",
"stats"
],
"offlineNetworkRequests": 0,
"errors": []
},
{
"browser": "webkit",
"checked": [
"shell",
"presenter",
"remote",
"party",
"share",
"stats"
],
"offlineNetworkRequests": 0,
"errors": []
}
]

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,135 @@
{
"date": "2026-10-08T04:01:09.552Z",
"frontendCommit": null,
"sourceRoot": null,
"sourceCommit": "4b1f5204f8fcd207305ee50fff29985497e58e3b",
"frontendBuildTag": "2bf76ad9d08e",
"commit": "4b1f5204f8fcd207305ee50fff29985497e58e3b",
"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": 44,
"min": 44,
"max": 44,
"values": [
44
]
},
"lcp": {
"median": 44,
"min": 44,
"max": 44,
"values": [
44
]
},
"domContentLoaded": {
"median": 151,
"min": 151,
"max": 151,
"values": [
151
]
},
"bootDone": {
"median": 157,
"min": 157,
"max": 157,
"values": [
157
]
},
"reloadDuration": {
"median": 173,
"min": 173,
"max": 173,
"values": [
173
]
}
}
}
},
"webkit": {
"lte": {
"offline": {
"requestCount": {
"median": 0,
"min": 0,
"max": 0,
"values": [
0
]
},
"wireBytes": {
"median": 0,
"min": 0,
"max": 0,
"values": [
0
]
},
"fcp": {
"median": 68,
"min": 68,
"max": 68,
"values": [
68
]
},
"lcp": {
"median": 101,
"min": 101,
"max": 101,
"values": [
101
]
},
"domContentLoaded": {
"median": 98,
"min": 98,
"max": 98,
"values": [
98
]
},
"bootDone": {
"median": 102,
"min": 102,
"max": 102,
"values": [
102
]
},
"reloadDuration": {
"median": 118,
"min": 118,
"max": 118,
"values": [
118
]
}
}
}
}
}
}

View File

@@ -0,0 +1,135 @@
{
"date": "2026-10-09T01:15:49.802Z",
"frontendCommit": null,
"sourceRoot": null,
"sourceCommit": "71608c2ce81207ca21c8adbc49edbc2893f5170e",
"frontendBuildTag": "2bf76ad9d08e",
"commit": "71608c2ce81207ca21c8adbc49edbc2893f5170e",
"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": 88,
"min": 88,
"max": 88,
"values": [
88
]
},
"lcp": {
"median": 88,
"min": 88,
"max": 88,
"values": [
88
]
},
"domContentLoaded": {
"median": 299,
"min": 299,
"max": 299,
"values": [
299
]
},
"bootDone": {
"median": 305,
"min": 305,
"max": 305,
"values": [
305
]
},
"reloadDuration": {
"median": 349,
"min": 349,
"max": 349,
"values": [
349
]
}
}
}
},
"webkit": {
"lte": {
"offline": {
"requestCount": {
"median": 0,
"min": 0,
"max": 0,
"values": [
0
]
},
"wireBytes": {
"median": 0,
"min": 0,
"max": 0,
"values": [
0
]
},
"fcp": {
"median": 164,
"min": 164,
"max": 164,
"values": [
164
]
},
"lcp": {
"median": 253,
"min": 253,
"max": 253,
"values": [
253
]
},
"domContentLoaded": {
"median": 241,
"min": 241,
"max": 241,
"values": [
241
]
},
"bootDone": {
"median": 256,
"min": 256,
"max": 256,
"values": [
256
]
},
"reloadDuration": {
"median": 299,
"min": 299,
"max": 299,
"values": [
299
]
}
}
}
}
}
}

File diff suppressed because it is too large Load Diff