UNPKG

@yuebai008/cli

Version:

Command line interface for rapid qg-minigame development

1 lines 15.1 kB
import*as Common from"../../core/common/common.js";import*as Host from"../../core/host/host.js";import*as i18n from"../../core/i18n/i18n.js";import*as SDK from"../../core/sdk/sdk.js";import*as Logs from"../../models/logs/logs.js";import*as ObjectUI from"../../ui/legacy/components/object_ui/object_ui.js";import*as UI from"../../ui/legacy/legacy.js";import{Events}from"./NetworkTimeCalculator.js";import networkingTimingTableStyles from"./networkTimingTable.css.js";const UIStrings={receivingPush:"Receiving `Push`",queueing:"Queueing",stalled:"Stalled",initialConnection:"Initial connection",dnsLookup:"DNS Lookup",proxyNegotiation:"Proxy negotiation",readingPush:"Reading `Push`",contentDownload:"Content Download",requestSent:"Request sent",requestToServiceworker:"Request to `ServiceWorker`",startup:"Startup",respondwith:"respondWith",ssl:"SSL",total:"Total",waitingTtfb:"Waiting for server response",label:"Label",waterfall:"Waterfall",duration:"Duration",queuedAtS:"Queued at {PH1}",startedAtS:"Started at {PH1}",serverPush:"Server Push",resourceScheduling:"Resource Scheduling",connectionStart:"Connection Start",requestresponse:"Request/Response",cautionRequestIsNotFinishedYet:"CAUTION: request is not finished yet!",explanation:"Explanation",serverTiming:"Server Timing",time:"TIME",theServerTimingApi:"the Server Timing API",duringDevelopmentYouCanUseSToAdd:"During development, you can use {PH1} to add insights into the server-side timing of this request.",durationC:"DURATION",originalRequest:"Original Request",responseReceived:"Response Received",unknown:"Unknown",sourceOfResponseS:"Source of response: {PH1}",cacheStorageCacheNameS:"Cache storage cache name: {PH1}",cacheStorageCacheNameUnknown:"Cache storage cache name: Unknown",retrievalTimeS:"Retrieval Time: {PH1}",serviceworkerCacheStorage:"`ServiceWorker` cache storage",fromHttpCache:"From HTTP cache",networkFetch:"Network fetch",fallbackCode:"Fallback code"},str_=i18n.i18n.registerUIStrings("panels/network/RequestTimingView.ts",UIStrings),i18nString=i18n.i18n.getLocalizedString.bind(void 0,str_);export class RequestTimingView extends UI.Widget.VBox{request;calculator;lastMinimumBoundary;tableElement;constructor(e,t){super(),this.element.classList.add("resource-timing-view"),this.request=e,this.calculator=t,this.lastMinimumBoundary=-1}static timeRangeTitle(e){switch(e){case RequestTimeRangeNames.Push:return i18nString(UIStrings.receivingPush);case RequestTimeRangeNames.Queueing:return i18nString(UIStrings.queueing);case RequestTimeRangeNames.Blocking:return i18nString(UIStrings.stalled);case RequestTimeRangeNames.Connecting:return i18nString(UIStrings.initialConnection);case RequestTimeRangeNames.DNS:return i18nString(UIStrings.dnsLookup);case RequestTimeRangeNames.Proxy:return i18nString(UIStrings.proxyNegotiation);case RequestTimeRangeNames.ReceivingPush:return i18nString(UIStrings.readingPush);case RequestTimeRangeNames.Receiving:return i18nString(UIStrings.contentDownload);case RequestTimeRangeNames.Sending:return i18nString(UIStrings.requestSent);case RequestTimeRangeNames.ServiceWorker:return i18nString(UIStrings.requestToServiceworker);case RequestTimeRangeNames.ServiceWorkerPreparation:return i18nString(UIStrings.startup);case RequestTimeRangeNames.ServiceWorkerRespondWith:return i18nString(UIStrings.respondwith);case RequestTimeRangeNames.SSL:return i18nString(UIStrings.ssl);case RequestTimeRangeNames.Total:return i18nString(UIStrings.total);case RequestTimeRangeNames.Waiting:return i18nString(UIStrings.waitingTtfb);default:return e}}static calculateRequestTimeRanges(e,t){const i=[];function n(e,t,n){t<Number.MAX_VALUE&&t<=n&&i.push({name:e,start:t,end:n})}function r(e){for(let t=0;t<e.length;++t)if(e[t]>0)return e[t]}function s(e,t,i){t>=0&&i>=0&&n(e,c+t/1e3,c+i/1e3)}const a=e.timing;if(!a){const t=-1!==e.issueTime()?e.issueTime():-1!==e.startTime?e.startTime:0,r=-1!==e.issueTime()&&-1!==e.startTime&&e.issueTime()!==e.startTime,s=-1===e.responseReceivedTime?r?e.startTime:Number.MAX_VALUE:e.responseReceivedTime,a=-1===e.endTime?Number.MAX_VALUE:e.endTime;n(RequestTimeRangeNames.Total,t,a),n(RequestTimeRangeNames.Blocking,t,s);return n(-1===e.responseReceivedTime?RequestTimeRangeNames.Connecting:RequestTimeRangeNames.Receiving,s,a),i}const o=e.issueTime(),c=a.requestTime,l=r([e.endTime,e.responseReceivedTime])||c;if(n(RequestTimeRangeNames.Total,o<c?o:c,l),a.pushStart){const e=a.pushEnd||l;e>t&&n(RequestTimeRangeNames.Push,Math.max(a.pushStart,t),e)}o<c&&n(RequestTimeRangeNames.Queueing,o,c);const g=1e3*(e.responseReceivedTime-c);if(e.fetchedViaServiceWorker)s(RequestTimeRangeNames.Blocking,0,a.workerStart),s(RequestTimeRangeNames.ServiceWorkerPreparation,a.workerStart,a.workerReady),s(RequestTimeRangeNames.ServiceWorkerRespondWith,a.workerFetchStart,a.workerRespondWithSettled),s(RequestTimeRangeNames.ServiceWorker,a.workerReady,a.sendEnd),s(RequestTimeRangeNames.Waiting,a.sendEnd,g);else if(!a.pushStart){const e=r([a.dnsStart,a.connectStart,a.sendStart,g])||0;s(RequestTimeRangeNames.Blocking,0,e),s(RequestTimeRangeNames.Proxy,a.proxyStart,a.proxyEnd),s(RequestTimeRangeNames.DNS,a.dnsStart,a.dnsEnd),s(RequestTimeRangeNames.Connecting,a.connectStart,a.connectEnd),s(RequestTimeRangeNames.SSL,a.sslStart,a.sslEnd),s(RequestTimeRangeNames.Sending,a.sendStart,a.sendEnd),s(RequestTimeRangeNames.Waiting,Math.max(a.sendEnd,a.connectEnd,a.dnsEnd,a.proxyEnd,e),g)}return-1!==e.endTime&&n(a.pushStart?RequestTimeRangeNames.ReceivingPush:RequestTimeRangeNames.Receiving,e.responseReceivedTime,l),i}static createTimingTable(e,t){const i=document.createElement("table");i.classList.add("network-timing-table");const n=i.createChild("colgroup");n.createChild("col","labels"),n.createChild("col","bars"),n.createChild("col","duration");const r=RequestTimingView.calculateRequestTimeRanges(e,t.minimumBoundary()),s=r.map((e=>e.start)).reduce(((e,t)=>Math.min(e,t))),a=r.map((e=>e.end)).reduce(((e,t)=>Math.max(e,t))),o=100/(a-s);let c,l,g,m,d=0;const u=i.createChild("thead","network-timing-start"),h=u.createChild("tr"),S=h.createChild("th");S.createChild("span","network-timing-hidden-header").textContent=i18nString(UIStrings.label),S.scope="col";const R=h.createChild("th");R.createChild("span","network-timing-hidden-header").textContent=i18nString(UIStrings.waterfall),R.scope="col";const T=h.createChild("th");T.createChild("span","network-timing-hidden-header").textContent=i18nString(UIStrings.duration),T.scope="col";const p=u.createChild("tr").createChild("td"),C=u.createChild("tr").createChild("td");let k;p.colSpan=C.colSpan=3,UI.UIUtils.createTextChild(p,i18nString(UIStrings.queuedAtS,{PH1:t.formatValue(e.issueTime(),2)})),UI.UIUtils.createTextChild(C,i18nString(UIStrings.startedAtS,{PH1:t.formatValue(e.startTime,2)}));for(let e=0;e<r.length;++e){const n=r[e],u=n.name;if(u===RequestTimeRangeNames.Total){d=n.end-n.start;continue}u===RequestTimeRangeNames.Push?b(i18nString(UIStrings.serverPush)):u===RequestTimeRangeNames.Queueing?m||(m=b(i18nString(UIStrings.resourceScheduling))):ConnectionSetupRangeNames.has(u)?c||(c=b(i18nString(UIStrings.connectionStart))):ServiceWorkerRangeNames.has(u)?l||(l=b("Service Worker")):g||(g=b(i18nString(UIStrings.requestresponse)));const h=o*(n.start-s);k=o*(a-n.end);const S=n.end-n.start,R=i.createChild("tr"),T=R.createChild("td");UI.UIUtils.createTextChild(T,RequestTimingView.timeRangeTitle(u));const p=R.createChild("td").createChild("div","network-timing-row"),C=p.createChild("span","network-timing-bar "+u);C.style.left=h+"%",C.style.right=k+"%",C.textContent="​",UI.ARIAUtils.setLabel(p,i18nString(UIStrings.startedAtS,{PH1:t.formatValue(n.start,2)}));R.createChild("td").createChild("div","network-timing-bar-title").textContent=i18n.TimeUtilities.secondsToString(S,!0),"serviceworker-respondwith"===n.name&&(T.classList.add("network-fetch-timing-bar-clickable"),i.createChild("tr","network-fetch-timing-bar-details"),T.setAttribute("tabindex","0"),T.setAttribute("role","switch"),UI.ARIAUtils.setChecked(T,!1))}if(!e.finished&&!e.preserved){const e=i.createChild("tr").createChild("td","caution");e.colSpan=3,UI.UIUtils.createTextChild(e,i18nString(UIStrings.cautionRequestIsNotFinishedYet))}const U=i.createChild("tr","network-timing-footer"),w=U.createChild("td");w.colSpan=1,w.appendChild(UI.XLink.XLink.create("https://developer.chrome.com/docs/devtools/network/reference/#timing-explanation",i18nString(UIStrings.explanation))),U.createChild("td"),UI.UIUtils.createTextChild(U.createChild("td"),i18n.TimeUtilities.secondsToString(d,!0));const v=e.serverTimings,q=void 0===k?100:k,I=i.createChild("tr","network-timing-table-header").createChild("td");I.colSpan=3,I.createChild("hr","break");const f=i.createChild("tr","network-timing-table-header");if(UI.UIUtils.createTextChild(f.createChild("td"),i18nString(UIStrings.serverTiming)),f.createChild("td"),UI.UIUtils.createTextChild(f.createChild("td"),i18nString(UIStrings.time)),!v){const e=i.createChild("tr").createChild("td");e.colSpan=3;const t=UI.XLink.XLink.create("https://web.dev/custom-metrics/#server-timing-api",i18nString(UIStrings.theServerTimingApi));return e.appendChild(i18n.i18n.getFormatLocalizedString(str_,UIStrings.duringDevelopmentYouCanUseSToAdd,{PH1:t})),i}return v.filter((e=>"total"!==e.metric.toLowerCase())).forEach((e=>N(e,q))),v.filter((e=>"total"===e.metric.toLowerCase())).forEach((e=>N(e,q))),i;function N(e,t){const n=new Common.Color.Generator({min:0,max:360,count:36},{min:50,max:80,count:void 0},80),r="total"===e.metric.toLowerCase(),c=i.createChild("tr",r?"network-timing-footer":"server-timing-row"),l=c.createChild("td","network-timing-metric"),g=e.description||e.metric;UI.UIUtils.createTextChild(l,g),UI.Tooltip.Tooltip.install(l,g);const m=c.createChild("td").createChild("div","network-timing-row");if(null===e.value)return;const d=o*(a-s-e.value/1e3);if(d>=0){const i=m.createChild("span","network-timing-bar server-timing");i.style.left=d+"%",i.style.right=t+"%",i.textContent="​",r||(i.style.backgroundColor=n.colorForID(e.metric))}c.createChild("td").createChild("div","network-timing-bar-title").textContent=i18n.TimeUtilities.millisToString(e.value,!0)}function b(e){const t=i.createChild("tr","network-timing-table-header"),n=t.createChild("td");return UI.UIUtils.createTextChild(n,e),UI.ARIAUtils.markAsHeading(n,2),UI.UIUtils.createTextChild(t.createChild("td"),""),UI.UIUtils.createTextChild(t.createChild("td"),i18nString(UIStrings.durationC)),t}}constructFetchDetailsView(){if(!this.tableElement)return;const e=this.tableElement.ownerDocument,t=e.querySelector(".network-fetch-timing-bar-details");if(!t)return;t.classList.add("network-fetch-timing-bar-details-collapsed"),self.onInvokeElement(this.tableElement,this.onToggleFetchDetails.bind(this,t));const i=new UI.TreeOutline.TreeOutlineInShadow;t.appendChild(i.element);const n=Logs.NetworkLog.NetworkLog.instance().originalRequestForURL(this.request.url());if(n){const e=SDK.RemoteObject.RemoteObject.fromLocalObject(n),t=new ObjectUI.ObjectPropertiesSection.RootElement(e);t.title=i18nString(UIStrings.originalRequest),i.appendChild(t)}const r=Logs.NetworkLog.NetworkLog.instance().originalResponseForURL(this.request.url());if(r){const e=SDK.RemoteObject.RemoteObject.fromLocalObject(r),t=new ObjectUI.ObjectPropertiesSection.RootElement(e);t.title=i18nString(UIStrings.responseReceived),i.appendChild(t)}const s=e.createElement("div");s.classList.add("network-fetch-details-treeitem");let a=i18nString(UIStrings.unknown);const o=this.request.serviceWorkerResponseSource();o&&(a=this.getLocalizedResponseSourceForCode(o)),s.textContent=i18nString(UIStrings.sourceOfResponseS,{PH1:a});const c=new UI.TreeOutline.TreeElement(s);i.appendChild(c);const l=e.createElement("div");l.classList.add("network-fetch-details-treeitem");const g=this.request.getResponseCacheStorageCacheName();l.textContent=g?i18nString(UIStrings.cacheStorageCacheNameS,{PH1:g}):i18nString(UIStrings.cacheStorageCacheNameUnknown);const m=new UI.TreeOutline.TreeElement(l);i.appendChild(m);const d=this.request.getResponseRetrievalTime();if(d){const t=e.createElement("div");t.classList.add("network-fetch-details-treeitem"),t.textContent=i18nString(UIStrings.retrievalTimeS,{PH1:d.toString()});const n=new UI.TreeOutline.TreeElement(t);i.appendChild(n)}}getLocalizedResponseSourceForCode(e){switch(e){case"cache-storage":return i18nString(UIStrings.serviceworkerCacheStorage);case"http-cache":return i18nString(UIStrings.fromHttpCache);case"network":return i18nString(UIStrings.networkFetch);default:return i18nString(UIStrings.fallbackCode)}}onToggleFetchDetails(e,t){if(!t.target)return;const i=t.target;if(i.classList.contains("network-fetch-timing-bar-clickable")){e.classList.contains("network-fetch-timing-bar-details-collapsed")&&Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelServiceWorkerRespondWith);const t="true"===i.getAttribute("aria-checked");i.setAttribute("aria-checked",String(!t)),e.classList.toggle("network-fetch-timing-bar-details-collapsed"),e.classList.toggle("network-fetch-timing-bar-details-expanded")}}wasShown(){this.request.addEventListener(SDK.NetworkRequest.Events.TimingChanged,this.refresh,this),this.request.addEventListener(SDK.NetworkRequest.Events.FinishedLoading,this.refresh,this),this.calculator.addEventListener(Events.BoundariesChanged,this.boundaryChanged,this),this.registerCSSFiles([networkingTimingTableStyles]),this.refresh()}willHide(){this.request.removeEventListener(SDK.NetworkRequest.Events.TimingChanged,this.refresh,this),this.request.removeEventListener(SDK.NetworkRequest.Events.FinishedLoading,this.refresh,this),this.calculator.removeEventListener(Events.BoundariesChanged,this.boundaryChanged,this)}refresh(){this.tableElement&&this.tableElement.remove(),this.tableElement=RequestTimingView.createTimingTable(this.request,this.calculator),this.tableElement.classList.add("resource-timing-table"),this.element.appendChild(this.tableElement),this.request.fetchedViaServiceWorker&&this.constructFetchDetailsView()}boundaryChanged(){const e=this.calculator.minimumBoundary();e!==this.lastMinimumBoundary&&(this.lastMinimumBoundary=e,this.refresh())}}export var RequestTimeRangeNames;!function(e){e.Push="push",e.Queueing="queueing",e.Blocking="blocking",e.Connecting="connecting",e.DNS="dns",e.Proxy="proxy",e.Receiving="receiving",e.ReceivingPush="receiving-push",e.Sending="sending",e.ServiceWorker="serviceworker",e.ServiceWorkerPreparation="serviceworker-preparation",e.ServiceWorkerRespondWith="serviceworker-respondwith",e.SSL="ssl",e.Total="total",e.Waiting="waiting"}(RequestTimeRangeNames||(RequestTimeRangeNames={}));export const ServiceWorkerRangeNames=new Set([RequestTimeRangeNames.ServiceWorker,RequestTimeRangeNames.ServiceWorkerPreparation,RequestTimeRangeNames.ServiceWorkerRespondWith]);export const ConnectionSetupRangeNames=new Set([RequestTimeRangeNames.Queueing,RequestTimeRangeNames.Blocking,RequestTimeRangeNames.Connecting,RequestTimeRangeNames.DNS,RequestTimeRangeNames.Proxy,RequestTimeRangeNames.SSL]);