@react-native/debugger-frontend
Version:
Debugger frontend for React Native based on Chrome DevTools
2 lines (1 loc) • 9.16 kB
JavaScript
import*as t from"../graph/graph.js";import*as e from"../core/core.js";class i{static getScriptUrls(e,i){const s=new Set;return e.traverse((e=>{e.type===t.BaseNode.types.NETWORK&&"Script"===e.request.resourceType&&i?.(e)&&s.add(e.request.url)})),s}static get coefficients(){throw new e.LanternError("coefficients unimplemented!")}static getScaledCoefficients(t){return this.coefficients}static getOptimisticGraph(t,i){throw new e.LanternError("Optimistic graph unimplemented!")}static getPessimisticGraph(t,i){throw new e.LanternError("Pessmistic graph unimplemented!")}static getEstimateFromSimulation(t,e){return t}static compute(t,e){const{simulator:i,graph:s,processedNavigation:r}=t,n=this.name.replace("Lantern",""),a=this.getOptimisticGraph(s,r),o=this.getPessimisticGraph(s,r);let c={label:`optimistic${n}`};const m=i.simulate(a,c);c={label:`pessimistic${n}`};const p=i.simulate(o,c),u=this.getEstimateFromSimulation(m,{...e,optimistic:!0}),d=this.getEstimateFromSimulation(p,{...e,optimistic:!1}),l=this.getScaledCoefficients(i.rtt),g=l.intercept>0?Math.min(1,u.timeInMs/1e3):1;return{timing:l.intercept*g+l.optimistic*u.timeInMs+l.pessimistic*d.timeInMs,optimisticEstimate:u,pessimisticEstimate:d,optimisticGraph:a,pessimisticGraph:o}}}class s extends i{static get coefficients(){return{intercept:0,optimistic:.5,pessimistic:.5}}static getRenderBlockingNodeData(e,{cutoffTimestamp:s,treatNodeAsRenderBlocking:r,additionalCpuNodesToTreatAsRenderBlocking:n}){const a=new Map,o=[];e.traverse((e=>{if(e.type===t.BaseNode.types.CPU){e.startTime<=s&&o.push(e);const t=e.getEvaluateScriptURLs();for(const i of t){const t=a.get(i)||e;a.set(i,e.startTime<t.startTime?e:t)}}})),o.sort(((t,e)=>t.startTime-e.startTime));const c=i.getScriptUrls(e,(t=>t.endTime<=s&&r(t))),m=new Set,p=new Set;for(const t of c){const e=a.get(t);e&&(o.includes(e)?p.add(e.id):m.add(t))}const u=o.find((t=>t.didPerformLayout()));u&&p.add(u.id);const d=o.find((t=>t.childEvents.some((t=>"Paint"===t.name))));d&&p.add(d.id);const l=o.find((t=>t.childEvents.some((t=>"ParseHTML"===t.name))));return l&&p.add(l.id),n&&o.filter(n).forEach((t=>p.add(t.id))),{definitelyNotRenderBlockingScriptUrls:m,renderBlockingCpuNodeIds:p}}static getFirstPaintBasedGraph(e,{cutoffTimestamp:i,treatNodeAsRenderBlocking:s,additionalCpuNodesToTreatAsRenderBlocking:r}){const n=this.getRenderBlockingNodeData(e,{cutoffTimestamp:i,treatNodeAsRenderBlocking:s,additionalCpuNodesToTreatAsRenderBlocking:r}),{definitelyNotRenderBlockingScriptUrls:a,renderBlockingCpuNodeIds:o}=n;return e.cloneWithRelationships((e=>{if(e.type===t.BaseNode.types.NETWORK){if((e.endTime>i||e.startTime>i)&&!e.isMainDocument())return!1;const t=e.request.url;return!a.has(t)&&s(e)}return o.has(e.id)}))}static getOptimisticGraph(t,e){return this.getFirstPaintBasedGraph(t,{cutoffTimestamp:e.timestamps.firstContentfulPaint,treatNodeAsRenderBlocking:t=>t.hasRenderBlockingPriority()&&"script"!==t.initiatorType})}static getPessimisticGraph(t,e){return this.getFirstPaintBasedGraph(t,{cutoffTimestamp:e.timestamps.firstContentfulPaint,treatNodeAsRenderBlocking:t=>t.hasRenderBlockingPriority()})}}class r extends i{static get coefficients(){return{intercept:0,optimistic:.45,pessimistic:.55}}static getOptimisticGraph(e){return e.cloneWithRelationships((e=>{if(e.type===t.BaseNode.types.CPU)return e.duration>2e4;const i="Image"===e.request.resourceType,s="Script"===e.request.resourceType;return!i&&(s||"High"===e.request.priority||"VeryHigh"===e.request.priority)}))}static getPessimisticGraph(t){return t}static getEstimateFromSimulation(t,i){if(!i.lcpResult)throw new e.LanternError("missing lcpResult");const s=r.getLastLongTaskEndTime(t.nodeTimings),n=i.optimistic?i.lcpResult.optimisticEstimate.timeInMs:i.lcpResult.pessimisticEstimate.timeInMs;return{timeInMs:Math.max(n,s),nodeTimings:t.nodeTimings}}static compute(t,i){const s=i?.lcpResult;if(!s)throw new e.LanternError("LCP is required to calculate the Interactive metric");const r=super.compute(t,i);return r.timing=Math.max(r.timing,s.timing),r}static getLastLongTaskEndTime(e,i=50){return Array.from(e.entries()).filter((([e,s])=>e.type===t.BaseNode.types.CPU&&s.duration>i)).map((([t,e])=>e.endTime)).reduce(((t,e)=>Math.max(t||0,e||0)),0)}}class n extends i{static get coefficients(){return{intercept:0,optimistic:.5,pessimistic:.5}}static isNotLowPriorityImageNode(t){if("network"!==t.type)return!0;const e="Image"===t.request.resourceType,i="Low"===t.request.priority||"VeryLow"===t.request.priority;return!e||!i}static getOptimisticGraph(t,i){const r=i.timestamps.largestContentfulPaint;if(!r)throw new e.LanternError("NO_LCP");return s.getFirstPaintBasedGraph(t,{cutoffTimestamp:r,treatNodeAsRenderBlocking:n.isNotLowPriorityImageNode})}static getPessimisticGraph(t,i){const r=i.timestamps.largestContentfulPaint;if(!r)throw new e.LanternError("NO_LCP");return s.getFirstPaintBasedGraph(t,{cutoffTimestamp:r,treatNodeAsRenderBlocking:t=>!0,additionalCpuNodesToTreatAsRenderBlocking:t=>t.didPerformLayout()})}static getEstimateFromSimulation(t){const e=Array.from(t.nodeTimings.entries()).filter((t=>n.isNotLowPriorityImageNode(t[0]))).map((t=>t[1].endTime));return{timeInMs:Math.max(...e),nodeTimings:t.nodeTimings}}static compute(t,i){const s=i?.fcpResult;if(!s)throw new e.LanternError("FCP is required to calculate the LCP metric");const r=super.compute(t,i);return r.timing=Math.max(r.timing,s.timing),r}}class a extends i{static get coefficients(){return{intercept:0,optimistic:.5,pessimistic:.5}}static getOptimisticGraph(t){return t}static getPessimisticGraph(t){return t}static getEstimateFromSimulation(t,i){if(!i.fcpResult)throw new e.LanternError("missing fcpResult");const s=i.optimistic?i.fcpResult.pessimisticEstimate.timeInMs:i.fcpResult.optimisticEstimate.timeInMs,r=a.getTimingsAfterFCP(t.nodeTimings,s);return{timeInMs:Math.max(...r.map((t=>t.duration)),16),nodeTimings:t.nodeTimings}}static compute(t,i){const s=i?.fcpResult;if(!s)throw new e.LanternError("FCP is required to calculate the Max Potential FID metric");return super.compute(t,i)}static getTimingsAfterFCP(e,i){return Array.from(e.entries()).filter((([e,s])=>e.type===t.BaseNode.types.CPU&&s.endTime>i)).map((([t,e])=>e))}}class o extends i{static get coefficients(){return{intercept:0,optimistic:1.4,pessimistic:.4}}static getScaledCoefficients(t){const e=this.coefficients,i=Math.max((t-30)/120,0);return{intercept:e.intercept*i,optimistic:.5+(e.optimistic-.5)*i,pessimistic:.5+(e.pessimistic-.5)*i}}static getOptimisticGraph(t){return t}static getPessimisticGraph(t){return t}static getEstimateFromSimulation(t,i){if(!i.fcpResult)throw new e.LanternError("missing fcpResult");if(void 0===i.observedSpeedIndex)throw new e.LanternError("missing observedSpeedIndex");const s=i.fcpResult.pessimisticEstimate.timeInMs;return{timeInMs:i.optimistic?i.observedSpeedIndex:o.computeLayoutBasedSpeedIndex(t.nodeTimings,s),nodeTimings:t.nodeTimings}}static compute(t,i){const s=i?.fcpResult;if(!s)throw new e.LanternError("FCP is required to calculate the SpeedIndex metric");const r=super.compute(t,i);return r.timing=Math.max(r.timing,s.timing),r}static computeLayoutBasedSpeedIndex(e,i){const s=[];for(const[i,r]of e.entries())if(i.type===t.BaseNode.types.CPU&&i.childEvents.some((t=>"Layout"===t.name))){const t=Math.max(Math.log2(r.endTime-r.startTime),0);s.push({time:r.endTime,weight:t})}const r=s.map((t=>t.weight*Math.max(t.time,i))).reduce(((t,e)=>t+e),0),n=s.map((t=>t.weight)).reduce(((t,e)=>t+e),0);return n?r/n:i}}const c=50;function m(t,e,i,s){let r=c;if(s&&(r*=t.duration/s.duration),t.duration<r)return 0;if(t.end<e)return 0;if(t.start>i)return 0;const n=Math.max(t.start,e),a=Math.min(t.end,i)-n;return a<r?0:a-r}function p(t,e,i){if(i<=e)return 0;let s=0;for(const r of t)s+=m(r,e,i);return s}var u=Object.freeze({__proto__:null,BLOCKING_TIME_THRESHOLD:c,calculateSumOfBlockingTime:p,calculateTbtImpactForEvent:m});class d extends i{static get coefficients(){return{intercept:0,optimistic:.5,pessimistic:.5}}static getOptimisticGraph(t){return t}static getPessimisticGraph(t){return t}static getEstimateFromSimulation(t,i){if(!i.fcpResult)throw new e.LanternError("missing fcpResult");if(!i.interactiveResult)throw new e.LanternError("missing interactiveResult");const s=i.optimistic?i.fcpResult.pessimisticEstimate.timeInMs:i.fcpResult.optimisticEstimate.timeInMs,r=i.optimistic?i.interactiveResult.optimisticEstimate.timeInMs:i.interactiveResult.pessimisticEstimate.timeInMs,n=c;return{timeInMs:p(d.getTopLevelEvents(t.nodeTimings,n),s,r),nodeTimings:t.nodeTimings}}static compute(t,i){const s=i?.fcpResult;if(!s)throw new e.LanternError("FCP is required to calculate the TBT metric");const r=i?.fcpResult;if(!r)throw new e.LanternError("Interactive is required to calculate the TBT metric");return super.compute(t,i)}static getTopLevelEvents(e,i){const s=[];for(const[r,n]of e.entries())r.type===t.BaseNode.types.CPU&&(n.duration<i||s.push({start:n.startTime,end:n.endTime,duration:n.duration}));return s}}export{s as FirstContentfulPaint,r as Interactive,n as LargestContentfulPaint,a as MaxPotentialFID,i as Metric,o as SpeedIndex,u as TBTUtils,d as TotalBlockingTime};