Cache the page-owned app response before starting the worker
This commit is contained in:
@@ -346,3 +346,7 @@ 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.
|
||||
|
||||
@@ -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';
|
||||
@@ -63,6 +63,7 @@ function parseArgs() {
|
||||
compare: null,
|
||||
frontendCommit: null,
|
||||
sourceRoot: null,
|
||||
assertCold: false,
|
||||
};
|
||||
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
@@ -72,6 +73,7 @@ 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];
|
||||
@@ -774,6 +776,7 @@ async function main() {
|
||||
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)`);
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
@@ -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([]));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user