mirror of
https://github.com/jcreek/LivingDexTracker.git
synced 2026-09-16 02:22:17 +00:00
2042e5a65a
Measures the pokédex load against a local Supabase with a generated fixture, and compares runs so a regression shows up as a number rather than a hunch. Wired into test:ci and given its own job so the artifacts survive a failure.
47 lines
1.8 KiB
JavaScript
47 lines
1.8 KiB
JavaScript
import { readFile } from 'node:fs/promises';
|
|
const data = JSON.parse(await readFile(process.argv[2], 'utf8'));
|
|
const warm = data.results.filter((row) => row.run === 'warm');
|
|
const p75 = (values) => [...values].sort((a, b) => a - b)[Math.ceil(values.length * 0.75) - 1];
|
|
const groups = [...new Set(warm.map((row) => `${row.fixture}/${row.navigation}`))];
|
|
const paired = groups.map((group) => {
|
|
const rows = (host) =>
|
|
warm.filter((row) => `${row.fixture}/${row.navigation}` === group && row.host === host);
|
|
for (const host of ['netlify', 'cloudflare'])
|
|
if (rows(host).length < 30) throw new Error(`Insufficient ${host} warm samples for ${group}`);
|
|
return {
|
|
group,
|
|
netlify: p75(rows('netlify').map((row) => row.interactiveMs)),
|
|
cloudflare: p75(rows('cloudflare').map((row) => row.interactiveMs))
|
|
};
|
|
});
|
|
if (groups.length !== 4)
|
|
throw new Error(
|
|
'Expected national and scoped-form fixtures, each with direct and client navigation'
|
|
);
|
|
const netlify = p75(warm.filter((row) => row.host === 'netlify').map((row) => row.interactiveMs));
|
|
const cloudflare = p75(
|
|
warm.filter((row) => row.host === 'cloudflare').map((row) => row.interactiveMs)
|
|
);
|
|
const improvement = netlify - cloudflare;
|
|
const passes =
|
|
improvement >= 200 &&
|
|
improvement / netlify >= 0.2 &&
|
|
paired.every((row) => row.cloudflare <= row.netlify * 1.1);
|
|
console.log(
|
|
JSON.stringify(
|
|
{
|
|
overallP75: { netlify, cloudflare },
|
|
improvementMs: improvement,
|
|
improvementPercent: (100 * improvement) / netlify,
|
|
groups: paired,
|
|
performanceGatePassed: passes,
|
|
recommendation:
|
|
passes && data.compatibilityPassed && data.environment === 'deployed'
|
|
? 'Cloudflare qualifies for a migration proposal; review operating cost before cutover.'
|
|
: 'Retain Netlify: performance, deployed evidence or compatibility gate is unmet.'
|
|
},
|
|
null,
|
|
2
|
|
)
|
|
);
|