UNPKG

studiocms

Version:

Astro Native CMS for AstroDB. Built from the ground up by the Astro community.

63 lines (62 loc) 2.04 kB
function processWebVitalsRouteSummary(data) { const grouped = data.reduce( (acc, item) => { const key = `${item.route}-${item.name}`; if (!acc[key]) acc[key] = []; acc[key].push(item); return acc; }, {} ); const results = []; for (const metrics of Object.values(grouped)) { if (metrics.length < 4) continue; metrics.sort((a, b) => a.rating.localeCompare(b.rating) || a.value - b.value); const quartileSize = Math.ceil(metrics.length / 4); metrics.forEach((metric, index) => { metric.quartile = Math.floor(index / quartileSize) + 1; }); metrics.forEach((metric, index, arr) => { const nextItem = arr[index + 1]; metric.quartile_end = !nextItem || nextItem.quartile !== metric.quartile; }); results.push(...metrics.filter((metric) => metric.quartile === 3 && metric.quartile_end)); } const summaries = {}; for (const item of results) { const { route, name, rating, value } = item; const routeSummary = summaries[route] ||= { route, passingCoreWebVitals: true, metrics: {}, score: 0 }; routeSummary.metrics[name] = { rating, value, sampleSize: results.length }; if (["LCP", "CLS", "INP"].includes(name) && rating !== "good") { routeSummary.passingCoreWebVitals = false; } } return Object.values(summaries).filter( (route) => Boolean(route.metrics.CLS && route.metrics.LCP && route.metrics.INP) ).map((route) => ({ ...route, score: simpleScore( route.metrics.LCP.rating, route.metrics.CLS.rating, route.metrics.INP.rating ) })).sort((a, b) => a.score - b.score); } const weighting = { LCP: 0.4, CLS: 0.3, INP: 0.3 }; const scoring = { good: 1, "needs-improvement": 0.5, poor: 0 }; const simpleScore = (lcpRating, clsRating, inpRating) => scoring[lcpRating] * weighting.LCP + scoring[clsRating] * weighting.CLS + scoring[inpRating] * weighting.INP; export { processWebVitalsRouteSummary, scoring, simpleScore, weighting };