52 lines
2.3 KiB
JavaScript
52 lines
2.3 KiB
JavaScript
export const PERFORMANCE_BUDGETS = Object.freeze({
|
|
initialHtmlCriticalCss: 100 * 1024,
|
|
initialApplicationJs: 120 * 1024,
|
|
heroPoster: 220 * 1024,
|
|
initialFonts: 120 * 1024,
|
|
firstLiveScene: 650 * 1024,
|
|
projectVideo: 2.5 * 1024 * 1024,
|
|
projectVideoDurationSeconds: 10,
|
|
projectVideoWidth: 1280,
|
|
projectVideoHeight: 720,
|
|
projectStill: 400 * 1024,
|
|
chart: 100 * 1024,
|
|
deferredProjectVisuals: 2.5 * 1024 * 1024,
|
|
highTierExtras: 750 * 1024,
|
|
deferredNonVideo: 3.5 * 1024 * 1024,
|
|
imageSceneConcurrency: 2,
|
|
videoConcurrency: 1,
|
|
mobileTextureDimension: 2048,
|
|
lowTierGpuEstimate: 96 * 1024 * 1024,
|
|
highTierGpuEstimate: 192 * 1024 * 1024,
|
|
});
|
|
|
|
export const classifyArtifact = (path, source = '') => {
|
|
if (path === 'index.html') return 'initial-html';
|
|
if (/^assets\/index-[^/]+\.css$/u.test(path)) return 'critical-css';
|
|
if (/^assets\/index-[^/]+\.js$/u.test(path) && /import\(/u.test(source)) return 'initial-application-js';
|
|
if (/^assets\/environment-[^/]+\.js$/u.test(path)) return 'first-live-scene';
|
|
if (/\.(?:woff2?|ttf|otf)$/u.test(path)) return 'initial-fonts';
|
|
if (/^assets\/hero-[^/]+\.(?:avif|webp|png|jpe?g)$/u.test(path)) return 'hero-poster';
|
|
if (/^assets\/project-[^/]+\.(?:webm|mp4)$/u.test(path)) return 'project-video';
|
|
if (/^assets\/project-[^/]*chart[^/]*\.(?:avif|webp|png|jpe?g)$/u.test(path)) return 'chart';
|
|
if (/^assets\/project-[^/]+\.(?:avif|webp|png|jpe?g|svg)$/u.test(path)) return 'project-still';
|
|
if (/^(?:robots\.txt|sitemap\.xml|_headers\.example|_redirects\.example)$/u.test(path)) return 'release-metadata';
|
|
throw new Error(`Artifact is unclassified: ${path}`);
|
|
};
|
|
|
|
const thresholdByTotal = Object.freeze({
|
|
initialHtmlCriticalCss: PERFORMANCE_BUDGETS.initialHtmlCriticalCss,
|
|
initialApplicationJs: PERFORMANCE_BUDGETS.initialApplicationJs,
|
|
heroPoster: PERFORMANCE_BUDGETS.heroPoster,
|
|
initialFonts: PERFORMANCE_BUDGETS.initialFonts,
|
|
firstLiveScene: PERFORMANCE_BUDGETS.firstLiveScene,
|
|
deferredProjectVisuals: PERFORMANCE_BUDGETS.deferredProjectVisuals,
|
|
deferredNonVideo: PERFORMANCE_BUDGETS.deferredNonVideo,
|
|
});
|
|
|
|
export const evaluateBudgetTotals = (totals) => ({
|
|
violations: Object.entries(thresholdByTotal)
|
|
.filter(([budget, threshold]) => (totals[budget] ?? 0) > threshold)
|
|
.map(([budget, threshold]) => ({ budget, actual: totals[budget], threshold })),
|
|
});
|