@react-native/debugger-frontend
Version:
Debugger frontend for React Native based on Chrome DevTools
29 lines (28 loc) • 6.88 kB
JavaScript
import*as e from"../../../../core/i18n/i18n.js";import*as i from"../../../../models/trace/trace.js";import*as t from"../../../../ui/components/helpers/helpers.js";import*as s from"../../../../ui/lit-html/lit-html.js";const n=new CSSStyleSheet;n.replaceSync(".insight{display:block;width:auto;height:auto;margin:10px 0;padding:10px;border-radius:3px;overflow:hidden;border:1px solid var(--sys-color-outline);background-color:var(--sys-color-base);&.closed{background-color:var(--sys-color-neutral-container);border:none}&.closed:hover{background-color:var(--sys-color-state-disabled-container)}}.insight-title{color:var(--sys-color-on-base);margin-block:3px}.table-container dl{display:grid;grid-template-columns:2fr 1fr}.table-container dt{padding:3px}.table-container dd{display:grid;justify-items:end;margin-inline-start:auto}.insight-description{border-bottom:1px solid var(--sys-color-outline);padding-bottom:10px}.link{color:var(--sys-color-primary)}.dl-title{font-weight:bold}.dl-value{font-weight:bold}\n/*# sourceURL=sidebarInsight.css */\n");class o extends Event{name;navigationId;createOverlayFn;static eventName="insightactivated";constructor(e,i,t){super(o.eventName,{bubbles:!0,composed:!0}),this.name=e,this.navigationId=i,this.createOverlayFn=t}}class r extends Event{static eventName="insightdeactivated";constructor(){super(r.eventName,{bubbles:!0,composed:!0})}}class a extends HTMLElement{static litTagName=s.literal`devtools-performance-sidebar-insight`;#e=this.attachShadow({mode:"open"});#i=this.#t.bind(this);#s="";#n=!1;set data(e){this.#s=e.title,this.#n=e.expanded,t.ScheduledRender.scheduleRender(this,this.#i)}connectedCallback(){this.#e.adoptedStyleSheets=[n],t.ScheduledRender.scheduleRender(this,this.#i)}#t(){let e;e=this.#n?s.html`
<div class="insight">
<h3 class="insight-title">${this.#s}</h3>
<slot name="insight-description"></slot>
<slot name="insight-content"></slot>
</div>`:s.html`
<div class="insight closed">
<h3 class="insight-title">${this.#s}</h3>
</div>`,s.render(e,this.#e,{host:this})}}customElements.define("devtools-performance-sidebar-insight",a);var d,l=Object.freeze({__proto__:null,InsightActivated:o,InsightDeactivated:r,SidebarInsight:a});!function(e){e.ALL="All",e.INP="INP",e.LCP="LCP",e.CLS="CLS",e.OTHER="Other"}(d||(d={}));var c=Object.freeze({__proto__:null,get InsightsCategories(){return d}});const h="lcp-phases",g={timeToFirstByte:"Time to first byte",resourceLoadDelay:"Resource load delay",resourceLoadTime:"Resource load time",elementRenderDelay:"Element render delay"},m=e.i18n.registerUIStrings("panels/timeline/components/insights/LCPPhases.ts",g),p=e.i18n.getLocalizedString.bind(void 0,m);class u extends HTMLElement{static litTagName=s.literal`devtools-performance-lcp-by-phases`;#e=this.attachShadow({mode:"open"});#i=this.#t.bind(this);#s="LCP by Phase";#o=null;#r=null;#a=null;#d=d.ALL;set insights(e){this.#o=e,t.ScheduledRender.scheduleRender(this,this.#i)}set navigationId(e){this.#r=e,t.ScheduledRender.scheduleRender(this,this.#i)}set activeInsight(e){this.#a=e,t.ScheduledRender.scheduleRender(this,this.#i)}set activeCategory(e){this.#d=e,t.ScheduledRender.scheduleRender(this,this.#i)}#l(e,i){if(!e||!i)return[];const t=e.get(i);if(!t)return[];const s=t.LargestContentfulPaint;if(s instanceof Error)return[];const n=s.lcpMs,o=s.phases;if(!n||!o)return[];const{ttfb:r,loadDelay:a,loadTime:d,renderDelay:l}=o;if(a&&d){return[{phase:"Time to first byte",timing:r,percent:`${(100*r/n).toFixed(0)}%`},{phase:"Resource load delay",timing:a,percent:`${(100*a/n).toFixed(0)}%`},{phase:"Resource load duration",timing:d,percent:`${(100*d/n).toFixed(0)}%`},{phase:"Resource render delay",timing:l,percent:`${(100*l/n).toFixed(0)}%`}]}return[{phase:"Time to first byte",timing:r,percent:`${(100*r/n).toFixed(0)}%`},{phase:"Resource render delay",timing:l,percent:`${(100*l/n).toFixed(0)}%`}]}#c(){if(!this.#o||!this.#r)return[];const e=this.#o.get(this.#r);if(!e)return[];const t=e.LargestContentfulPaint;if(t instanceof Error)return[];const s=t.phases,n=t.lcpTs;if(!s||!n)return[];const o=i.Types.Timing.MicroSeconds(i.Helpers.Timing.millisecondsToMicroseconds(n)),r=[];if(s?.loadDelay||s?.loadTime){if(s?.loadDelay&&s?.loadTime){const e=i.Types.Timing.MicroSeconds(o-i.Helpers.Timing.millisecondsToMicroseconds(s.renderDelay)),t=i.Helpers.Timing.traceWindowFromMicroSeconds(e,o),n=i.Types.Timing.MicroSeconds(e-i.Helpers.Timing.millisecondsToMicroseconds(s.loadTime)),a=i.Helpers.Timing.traceWindowFromMicroSeconds(n,e),d=i.Types.Timing.MicroSeconds(n-i.Helpers.Timing.millisecondsToMicroseconds(s.loadDelay)),l=i.Helpers.Timing.traceWindowFromMicroSeconds(d,n),c=i.Types.Timing.MicroSeconds(d-i.Helpers.Timing.millisecondsToMicroseconds(s.ttfb)),h=i.Helpers.Timing.traceWindowFromMicroSeconds(c,d);r.push({bounds:h,label:p(g.timeToFirstByte)},{bounds:l,label:p(g.resourceLoadDelay)},{bounds:a,label:p(g.resourceLoadTime)},{bounds:t,label:p(g.elementRenderDelay)})}}else{const e=i.Types.Timing.MicroSeconds(o-i.Helpers.Timing.millisecondsToMicroseconds(s.renderDelay)),t=i.Helpers.Timing.traceWindowFromMicroSeconds(e,o),n=i.Types.Timing.MicroSeconds(e-i.Helpers.Timing.millisecondsToMicroseconds(s.ttfb)),a=i.Helpers.Timing.traceWindowFromMicroSeconds(n,e);r.push({bounds:a,label:p(g.timeToFirstByte)},{bounds:t,label:p(g.elementRenderDelay)})}return[{type:"TIMESPAN_BREAKDOWN",sections:r}]}#h(){this.#g()?this.dispatchEvent(new r):this.#r&&this.dispatchEvent(new o(h,this.#r,this.#c.bind(this)))}#m(e){return s.html`
<div class="insights" =${()=>this.#h()}>
<${a.litTagName} .data=${{title:this.#s,expanded:this.#g()}}>
<div slot="insight-description" class="insight-description">
Each
<x-link class="link" href="https://web.dev/articles/optimize-lcp#lcp-breakdown">phase has specific recommendations to improve.</x-link>
In an ideal load, the two delay phases should be quite short.
</div>
<div slot="insight-content" class="table-container">
<dl>
<dt class="dl-title">Phase</dt>
<dd class="dl-title">% of LCP</dd>
${e?.map((e=>s.html`
<dt>${e.phase}</dt>
<dd class="dl-value">${e.percent}</dd>
`))}
</dl>
</div>
</${l}>
</div>`}connectedCallback(){this.#e.adoptedStyleSheets=[n]}#p(){return this.#d===d.ALL||this.#d===d.LCP}#g(){const e=this.#a&&this.#a.name===h&&this.#a.navigationId===this.#r;return Boolean(e)}#u(e){return!!e&&e.length>0}#t(){const e=this.#l(this.#o,this.#r),i=this.#p()&&this.#u(e)?this.#m(e):s.nothing;s.render(i,this.#e,{host:this})}}customElements.define("devtools-performance-lcp-by-phases",u);var b=Object.freeze({__proto__:null,InsightName:h,LCPPhases:u});export{b as LCPPhases,l as SidebarInsight,c as Types};