ci: establish trusted quality baseline

This commit is contained in:
2026-07-15 17:34:17 +08:00
parent c277b3e6ca
commit 86ffbbcdbc
7 changed files with 136 additions and 17 deletions
+45
View File
@@ -14,6 +14,14 @@ const outputPath = resolve(
const routes = parseList(
process.env.PERF_ROUTES ?? "/splash,/chat,/subscription,/tip",
);
const enforceBudgets = process.env.PERF_BUNDLE_ENFORCE === "1";
const eagerClientJsBudgets = new Map([
["/splash", 650 * 1024],
["/chat", 675 * 1024],
["/subscription", 665 * 1024],
["/tip", 660 * 1024],
]);
const auditTargets = [
{
@@ -46,6 +54,19 @@ function main() {
const routeReports = routes.map((route) =>
analyzeRoute(route, asyncBoundariesByPath),
);
const budgetResults = routeReports.flatMap((route) => {
const budgetBytes = eagerClientJsBudgets.get(route.route);
if (budgetBytes === undefined) return [];
return [
{
route: route.route,
budgetBytes,
actualBytes: route.eagerClientJs.compressedBytes,
withinBudget: route.eagerClientJs.compressedBytes <= budgetBytes,
},
];
});
const packageJson = JSON.parse(
readFileSync(resolve(root, "package.json"), "utf8"),
);
@@ -54,6 +75,7 @@ function main() {
generatedAt: new Date().toISOString(),
nextVersion: packageJson.dependencies.next,
routes: routeReports,
eagerClientJsBudgets: budgetResults,
};
mkdirSync(dirname(outputPath), { recursive: true });
@@ -65,6 +87,7 @@ function main() {
"eager client JS": formatBytes(route.eagerClientJs.compressedBytes),
"async client JS": formatBytes(route.asyncClientJs.compressedBytes),
"total client JS": formatBytes(route.totalClientJs.compressedBytes),
budget: formatBudget(route, budgetResults),
})),
);
@@ -84,6 +107,22 @@ function main() {
}
console.log(`\nBundle summary written to ${outputPath}`);
if (!enforceBudgets) return;
const failures = budgetResults.filter((result) => !result.withinBudget);
if (failures.length === 0) {
console.log("All eager client JS budgets passed.");
return;
}
console.error("\nEager client JS budget exceeded:");
for (const failure of failures) {
console.error(
`- ${failure.route}: ${formatBytes(failure.actualBytes)} > ${formatBytes(failure.budgetBytes)}`,
);
}
process.exitCode = 1;
}
function analyzeRoute(route, boundariesByPath) {
@@ -297,6 +336,12 @@ function formatBytes(bytes) {
return `${(bytes / 1024).toFixed(1)} KiB`;
}
function formatBudget(route, budgetResults) {
const result = budgetResults.find((item) => item.route === route.route);
if (result === undefined) return "not set";
return `${result.withinBudget ? "pass" : "fail"} / ${formatBytes(result.budgetBytes)}`;
}
class FramedDataFile {
constructor(filePath) {
this.buffer = readFileSync(filePath);