@yuebai008/cli
Version:
Command line interface for rapid qg-minigame development
1 lines • 8.12 kB
JavaScript
import*as Platform from"../../../core/platform/platform.js";import*as Helpers from"../helpers/helpers.js";import*as Types from"../types/types.js";import{data as metaHandlerData}from"./MetaHandler.js";const metricScoresByFrameId=new Map;let allMarkerEvents=[];export function reset(){metricScoresByFrameId.clear(),pageLoadEventsArray=[],allMarkerEvents=[],selectedLCPCandidateEvents.clear()}let pageLoadEventsArray=[];const selectedLCPCandidateEvents=new Set;export const MarkerName=["MarkDOMContent","MarkLoad","firstPaint","firstContentfulPaint","largestContentfulPaint::Candidate"];const markerTypeGuards=[Types.TraceEvents.isTraceEventMarkDOMContent,Types.TraceEvents.isTraceEventMarkLoad,Types.TraceEvents.isTraceEventFirstPaint,Types.TraceEvents.isTraceEventFirstContentfulPaint,Types.TraceEvents.isTraceEventLargestContentfulPaintCandidate,Types.TraceEvents.isTraceEventNavigationStart];export function isTraceEventMarkerEvent(e){return markerTypeGuards.some((t=>t(e)))}const pageLoadEventTypeGuards=[...markerTypeGuards,Types.TraceEvents.isTraceEventInteractiveTime];export function eventIsPageLoadEvent(e){return pageLoadEventTypeGuards.some((t=>t(e)))}export function handleEvent(e){eventIsPageLoadEvent(e)&&pageLoadEventsArray.push(e)}function storePageLoadMetricAgainstNavigationId(e,t){const n=e.args.data?.navigationId;if(!n)throw new Error("Navigation event unexpectedly had no navigation ID.");const a=getFrameIdForPageLoadEvent(t),{rendererProcessesByFrame:r}=metaHandlerData(),i=r.get(a);if(!i)return;const s=i.get(t.pid);if(!s)return;if(Types.TraceEvents.isTraceEventNavigationStart(t))return;const o=s[0].window.min,c=s.at(-1)?.window.max||0;if(t.ts>=o&&t.ts<=c)if(Types.TraceEvents.isTraceEventFirstContentfulPaint(t)){const r=Types.Timing.MicroSeconds(t.ts-e.ts);storeMetricScore(a,n,{event:t,score:Helpers.Timing.formatMicrosecondsTime(r,{format:2,maximumFractionDigits:2}),metricName:"FCP",classification:scoreClassificationForFirstContentfulPaint(r),navigation:e})}else if(Types.TraceEvents.isTraceEventFirstPaint(t)){const r=Types.Timing.MicroSeconds(t.ts-e.ts);storeMetricScore(a,n,{event:t,score:Helpers.Timing.formatMicrosecondsTime(r,{format:2,maximumFractionDigits:2}),metricName:"FP",classification:"unclassified",navigation:e})}else if(Types.TraceEvents.isTraceEventMarkDOMContent(t)){const r=Types.Timing.MicroSeconds(t.ts-e.ts);storeMetricScore(a,n,{event:t,score:Helpers.Timing.formatMicrosecondsTime(r,{format:2,maximumFractionDigits:2}),metricName:"DCL",classification:scoreClassificationForDOMContentLoaded(r),navigation:e})}else if(Types.TraceEvents.isTraceEventInteractiveTime(t)){const r=Types.Timing.MicroSeconds(t.ts-e.ts);storeMetricScore(a,n,{event:t,score:Helpers.Timing.formatMicrosecondsTime(r,{format:2,maximumFractionDigits:2}),metricName:"TTI",classification:scoreClassificationForTimeToInteractive(r),navigation:e});const i=Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(t.args.args.total_blocking_time_ms));storeMetricScore(a,n,{event:t,score:Helpers.Timing.formatMicrosecondsTime(i,{format:1,maximumFractionDigits:2}),metricName:"TBT",classification:scoreClassificationForTotalBlockingTime(i),navigation:e})}else if(Types.TraceEvents.isTraceEventMarkLoad(t)){const r=Types.Timing.MicroSeconds(t.ts-e.ts);storeMetricScore(a,n,{event:t,score:Helpers.Timing.formatMicrosecondsTime(r,{format:2,maximumFractionDigits:2}),metricName:"L",classification:"unclassified",navigation:e})}else if(Types.TraceEvents.isTraceEventLargestContentfulPaintCandidate(t)){const r=t.args.data?.candidateIndex;if(!r)throw new Error("Largest Contenful Paint unexpectedly had no candidateIndex.");const i=Types.Timing.MicroSeconds(t.ts-e.ts),s={event:t,score:Helpers.Timing.formatMicrosecondsTime(i,{format:2,maximumFractionDigits:2}),metricName:"LCP",classification:scoreClassificationForLargestContentfulPaint(i),navigation:e},o=Platform.MapUtilities.getWithDefault(metricScoresByFrameId,a,(()=>new Map)),c=Platform.MapUtilities.getWithDefault(o,n,(()=>new Map)).get("LCP");if(void 0===c)return selectedLCPCandidateEvents.add(s.event),void storeMetricScore(a,n,s);const T=c.event;if(!Types.TraceEvents.isTraceEventLargestContentfulPaintCandidate(T))return;const d=T.args.data?.candidateIndex;if(!d)return;d<r&&(selectedLCPCandidateEvents.delete(T),selectedLCPCandidateEvents.add(s.event),storeMetricScore(a,n,s))}else if(!Types.TraceEvents.isTraceEventLayoutShift(t))return Platform.assertNever(t,`Unexpected event type: ${t}`)}function storeMetricScore(e,t,n){const a=Platform.MapUtilities.getWithDefault(metricScoresByFrameId,e,(()=>new Map)),r=Platform.MapUtilities.getWithDefault(a,t,(()=>new Map));r.delete(n.metricName),r.set(n.metricName,n)}export function getFrameIdForPageLoadEvent(e){if(Types.TraceEvents.isTraceEventFirstContentfulPaint(e)||Types.TraceEvents.isTraceEventInteractiveTime(e)||Types.TraceEvents.isTraceEventLargestContentfulPaintCandidate(e)||Types.TraceEvents.isTraceEventNavigationStart(e)||Types.TraceEvents.isTraceEventLayoutShift(e)||Types.TraceEvents.isTraceEventFirstPaint(e))return e.args.frame;if(Types.TraceEvents.isTraceEventMarkDOMContent(e)||Types.TraceEvents.isTraceEventMarkLoad(e)){const t=e.args.data?.frame;if(!t)throw new Error("MarkDOMContent unexpectedly had no frame ID.");return t}Platform.assertNever(e,`Unexpected event type: ${e}`)}function getNavigationForPageLoadEvent(e){if(Types.TraceEvents.isTraceEventFirstContentfulPaint(e)||Types.TraceEvents.isTraceEventLargestContentfulPaintCandidate(e)||Types.TraceEvents.isTraceEventFirstPaint(e)){const t=e.args.data?.navigationId;if(!t)throw new Error("Trace event unexpectedly had no navigation ID.");const{navigationsByNavigationId:n}=metaHandlerData(),a=n.get(t);return a||null}if(Types.TraceEvents.isTraceEventMarkDOMContent(e)||Types.TraceEvents.isTraceEventInteractiveTime(e)||Types.TraceEvents.isTraceEventLayoutShift(e)||Types.TraceEvents.isTraceEventMarkLoad(e)){const t=getFrameIdForPageLoadEvent(e),{navigationsByFrameId:n}=metaHandlerData();return Helpers.Trace.getNavigationForTraceEvent(e,t,n)}return Types.TraceEvents.isTraceEventNavigationStart(e)?null:Platform.assertNever(e,`Unexpected event type: ${e}`)}export function scoreClassificationForFirstContentfulPaint(e){const t=Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(1.8));let n="bad";return e<=Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(3))&&(n="ok"),e<=t&&(n="good"),n}export function scoreClassificationForTimeToInteractive(e){const t=Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(3.8));let n="bad";return e<=Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(7.3))&&(n="ok"),e<=t&&(n="good"),n}export function scoreClassificationForLargestContentfulPaint(e){const t=Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(2.5));let n="bad";return e<=Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(4))&&(n="ok"),e<=t&&(n="good"),n}export function scoreClassificationForDOMContentLoaded(e){return"unclassified"}export function scoreClassificationForTotalBlockingTime(e){const t=Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(200));let n="bad";return e<=Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(600))&&(n="ok"),e<=t&&(n="good"),n}function gatherFinalLCPEvents(){const e=[],t=[...metricScoresByFrameId.values()].flatMap((e=>[...e.values()]));for(let n=0;n<t.length;n++){const a=t[n].get("LCP");a&&a.event&&e.push(a.event)}return e}export async function finalize(){pageLoadEventsArray.sort(((e,t)=>e.ts-t.ts));for(const e of pageLoadEventsArray){const t=getNavigationForPageLoadEvent(e);t&&storePageLoadMetricAgainstNavigationId(t,e)}const e=gatherFinalLCPEvents(),t=metaHandlerData().mainFrameId,n=[...e,...pageLoadEventsArray.filter((e=>!Types.TraceEvents.isTraceEventLargestContentfulPaintCandidate(e)))].filter(isTraceEventMarkerEvent);allMarkerEvents=n.filter((e=>getFrameIdForPageLoadEvent(e)===t)).sort(((e,t)=>e.ts-t.ts))}export function data(){return{metricScoresByFrameId:new Map(metricScoresByFrameId),allMarkerEvents:[...allMarkerEvents]}}export function deps(){return["Meta"]}