UNPKG

studiocms

Version:

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

329 lines (299 loc) 9.8 kB
import type { WebVitalsResponseItem } from '../types.js'; // Misc Utils export function msToSeconds(ms: number): number { return ms / 1000; } // CLS Calculations // Combine all CLS values and calculate average export function calculateClsAverage(clsValues: number[]): number { const sum = clsValues.reduce((acc, curr) => acc + curr, 0); const average = sum / clsValues.length; // Round average to two decimal places return Math.round(average * 100) / 100; } // Get CLS data from Web Vitals API response // Return the Calculated average CLS value export const clsDataAverage = (webVitalData: WebVitalsResponseItem[]) => { const clsData: number[] = []; if (webVitalData) { for (const item of webVitalData) { if (item.name === 'CLS') { clsData.push(item.value); } } } return calculateClsAverage(clsData); }; // Calculate CLS score based on the average CLS value // Return the score as a string (Excellent, Good, Fair, Poor) // This is based on the https://web.dev/cls/ guidelines export function calculateClsScoreText(cls: number): string { if (cls <= 0.1) { return 'Excellent'; // Excellent } if (cls <= 0.25) { return 'Good'; // Good to Excellent } if (cls <= 0.5) { return 'Fair'; // Fair to Good } return 'Poor'; // Poor to Fair } // Calculate CLS score based on the average CLS value // Return the score as a percentage (0-100) // This is based on the https://web.dev/cls/ guidelines export function calculateClsScorePercent(cls: number): number { if (cls <= 0.1) { return 100; // Excellent } if (cls <= 0.25) { return Math.round(100 - ((cls - 0.1) / (0.25 - 0.1)) * 25); // Good to Excellent } if (cls <= 0.5) { return Math.round(75 - ((cls - 0.25) / (0.5 - 0.25)) * 25); // Fair to Good } return Math.round(50 - ((cls - 0.5) / (1 - 0.5)) * 50); // Poor to Fair } // Calculate CLS progress bar color based on the average CLS value // Return the color as a string (green, yellow, red) // This is based on the https://web.dev/cls/ guidelines export const progressBarClsColor = (clsData: number) => { if (clsData <= 0.25) { return 'green'; } if (clsData > 0.25 && clsData <= 0.5) { return 'yellow'; } return 'red'; }; // Calculate CLS progress bar track color based on the average CLS value // Return the color as a string (yellow, red) // This is based on the https://web.dev/cls/ guidelines export const progressBarClsTrackColor = (clsData: number) => { if (clsData <= 0.25) { return 'yellow'; } if (clsData > 0.25) { return 'red'; } /* v8 ignore start */ return 'red'; }; /* v8 ignore stop */ // Calculate CLS text color based on the average CLS value // Return the color as a string (green, yellow, red) // This is based on the https://web.dev/cls/ guidelines export const clsTextColor = (clsData: number) => { if (clsData <= 0.25) { return 'green'; } if (clsData > 0.25 && clsData <= 0.5) { return 'yellow'; } return 'red'; }; // LCP Calculations // Combine all LCP values and calculate average // Return the Calculated average LCP value export function calculateLcpAverage(lcpValues: number[]): number { const sum = lcpValues.reduce((acc, curr) => acc + curr, 0); const average = sum / lcpValues.length; // Round average to two decimal places return Math.floor(Math.round(average * 100) / 100); } // Get LCP data from Web Vitals API response // Return the Calculated average LCP value export const lcpDataAverage = (webVitalData: WebVitalsResponseItem[]) => { const lcpData: number[] = []; if (webVitalData) { for (const item of webVitalData) { if (item.name === 'LCP') { lcpData.push(item.value); } } } return calculateLcpAverage(lcpData); }; // Calculate LCP score based on the average LCP value // Return the score as a string (Excellent, Good, Fair, Poor) // This is based on the https://web.dev/lcp/ guidelines export function calculateLcpScoreText(lcp: number): string { if (msToSeconds(lcp) <= 2) { return 'Excellent'; // Excellent } if (msToSeconds(lcp) <= 4) { return 'Good'; // Good to Excellent } if (msToSeconds(lcp) <= 6) { return 'Fair'; // Fair to Good } return 'Poor'; // Poor to Fair } // Calculate LCP score based on the average LCP value // Return the score as a percentage (0-100) // This is based on the https://web.dev/lcp/ guidelines export function calculateLcpScorePercent(lcp: number): number { if (msToSeconds(lcp) <= 2) { return 100; // Excellent } if (msToSeconds(lcp) <= 4) { return Math.round(100 - ((lcp - 2) / (4 - 2)) * 50); // Good to Excellent } if (msToSeconds(lcp) <= 6) { return Math.round(50 - ((lcp - 4) / (6 - 4)) * 50); // Fair to Good } return Math.round(0 - ((lcp - 6) / (10 - 6)) * 50); // Poor to Fair } // Calculate LCP progress bar color based on the average LCP value // Return the color as a string (green, yellow, red) // This is based on the https://web.dev/lcp/ guidelines export const progressBarLcpColor = (lcpData: number) => { if (msToSeconds(lcpData) <= 2.5) { return 'green'; } if (msToSeconds(lcpData) > 2.5 && msToSeconds(lcpData) <= 4) { return 'yellow'; } return 'red'; }; // Calculate LCP progress bar track color based on the average LCP value // Return the color as a string (yellow, red) // This is based on the https://web.dev/lcp/ guidelines export const progressBarLcpTrackColor = (lcpData: number) => { if (msToSeconds(lcpData) <= 2.5) { return 'yellow'; } if (msToSeconds(lcpData) > 2.5) { return 'red'; } /* v8 ignore start */ return 'red'; }; /* v8 ignore stop */ // Calculate LCP text color based on the average LCP value // Return the color as a string (green, yellow, red) // This is based on the https://web.dev/lcp/ guidelines export const lcpTextColor = (lcpData: number) => { if (msToSeconds(lcpData) <= 2.5) { return 'green'; } if (msToSeconds(lcpData) > 2.5 && msToSeconds(lcpData) <= 4) { return 'yellow'; } return 'red'; }; // INP Calculations // Combine all INP values and calculate average // Return the Calculated average INP value export function calculateInpAverage(inpValues: number[]): number { const sum = inpValues.reduce((acc, curr) => acc + curr, 0); const average = sum / inpValues.length; // Round average to two decimal places return Math.round(average * 100) / 100; } // Get INP data from Web Vitals API response // Return the Calculated average INP value export function inpDataAverage(webVitalData: WebVitalsResponseItem[]): number { const inpData: number[] = []; if (webVitalData) { for (const item of webVitalData) { if (item.name === 'INP') { inpData.push(item.value); } } } return Math.floor(calculateInpAverage(inpData)); } // Calculate INP score based on the average INP value // Return the score as a string (Excellent, Good, Fair, Poor) // This is based on the https://web.dev/inp/ guidelines export function calculateInpScoreText(inp: number): string { if (inp <= 50) { return 'Excellent'; // Excellent } if (inp <= 100) { return 'Good'; // Good to Excellent } if (inp <= 200) { return 'Fair'; // Fair to Good } return 'Poor'; // Poor to Fair } // Calculate INP score based on the average INP value // Return the score as a percentage (0-100) // This is based on the https://web.dev/inp/ guidelines export function calculateInpScorePercent(inp: number): number { if (inp <= 50) { return 100; // Excellent } if (inp <= 100) { return Math.round(100 - ((inp - 50) / (100 - 50)) * 50); // Good to Excellent } if (inp <= 200) { return Math.round(50 - ((inp - 100) / (200 - 100)) * 50); // Fair to Good } return Math.round(0 - ((inp - 200) / (300 - 200)) * 50); // Poor to Fair } // Calculate INP progress bar color based on the average INP value // Return the color as a string (green, yellow, red) // This is based on the https://web.dev/inp/ guidelines export const progressBarInpColor = (inpData: number) => { if (inpData <= 100) { return 'green'; } if (inpData > 100 && inpData <= 200) { return 'yellow'; } return 'red'; }; // Calculate INP progress bar track color based on the average INP value // Return the color as a string (yellow, red) // This is based on the https://web.dev/inp/ guidelines export const progressBarInpTrackColor = (inpData: number) => { if (inpData <= 100) { return 'yellow'; } if (inpData > 100) { return 'red'; } /* v8 ignore start */ return 'red'; }; /* v8 ignore stop */ // Calculate INP text color based on the average INP value // Return the color as a string (green, yellow, red) // This is based on the https://web.dev/inp/ guidelines export const inpTextColor = (inpData: number) => { if (inpData <= 100) { return 'green'; } if (inpData > 100 && inpData <= 200) { return 'yellow'; } return 'red'; }; // // Pagespeed Insights Utils // export function generateLighthouseFetchUrl( url: string, strategy: 'mobile' | 'desktop' | 'mixed-content' = 'mobile' ): string { // Base URL for Google PageSpeed Insights API const baseUrl: string = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed'; // Final URL with encoded parameters const fetchUrl: string = `${baseUrl}?url=${encodeURIComponent(url)}&fields=lighthouseResult%2Fcategories%2F*%2Fscore&prettyPrint=false&strategy=${strategy}&category=performance&category=pwa&category=best-practices&category=accessibility&category=seo`; return fetchUrl; } // export const setProgressRing = (ProgressRing: SlProgressRing, value: number) => { // ProgressRing.value = value; // ProgressRing.textContent = value.toString(); // ProgressRing.style.color = value >= 90 ? 'green' : value >= 50 ? 'rgb(208, 208, 0)' : 'red'; // ProgressRing.style.setProperty( // '--indicator-color', // value >= 90 ? 'green' : value >= 50 ? 'yellow' : 'red' // ); // if (value < 90) { // ProgressRing.style.webkitTextStroke = '2px black;'; // } // };