@paulirish/trace_engine 0.0.44 → 0.0.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.tmp/tsbuildinfo/tsconfig.tsbuildinfo +1 -1
- package/core/platform/ArrayUtilities.d.ts +1 -1
- package/core/platform/ArrayUtilities.js.map +1 -1
- package/core/platform/DOMUtilities.js +1 -1
- package/core/platform/DOMUtilities.js.map +1 -1
- package/core/platform/MimeType.js.map +1 -1
- package/core/platform/NumberUtilities.js.map +1 -1
- package/core/platform/ServerTiming.d.ts +2 -2
- package/core/platform/ServerTiming.js.map +1 -1
- package/core/platform/StringUtilities.js +1 -1
- package/core/platform/StringUtilities.js.map +1 -1
- package/core/platform/Timing.d.ts +0 -1
- package/core/platform/Timing.js +0 -3
- package/core/platform/Timing.js.map +1 -1
- package/core/platform/TypedArrayUtilities.js +3 -2
- package/core/platform/TypedArrayUtilities.js.map +1 -1
- package/generated/protocol.d.ts +71 -4
- package/locales/af.json +184 -1
- package/locales/am.json +184 -1
- package/locales/ar.json +184 -1
- package/locales/as.json +184 -1
- package/locales/az.json +184 -1
- package/locales/be.json +184 -1
- package/locales/bg.json +184 -1
- package/locales/bn.json +184 -1
- package/locales/bs.json +184 -1
- package/locales/ca.json +184 -1
- package/locales/cs.json +184 -1
- package/locales/cy.json +184 -1
- package/locales/da.json +184 -1
- package/locales/de.json +184 -1
- package/locales/el.json +184 -1
- package/locales/en-GB.json +184 -1
- package/locales/en-US.json +201 -15
- package/locales/en-XL.json +201 -15
- package/locales/es-419.json +184 -1
- package/locales/es.json +184 -1
- package/locales/et.json +184 -1
- package/locales/eu.json +184 -1
- package/locales/fa.json +184 -1
- package/locales/fi.json +184 -1
- package/locales/fil.json +184 -1
- package/locales/fr-CA.json +184 -1
- package/locales/fr.json +184 -1
- package/locales/gl.json +184 -1
- package/locales/gu.json +184 -1
- package/locales/he.json +185 -2
- package/locales/hi.json +184 -1
- package/locales/hr.json +184 -1
- package/locales/hu.json +184 -1
- package/locales/hy.json +184 -1
- package/locales/id.json +184 -1
- package/locales/is.json +184 -1
- package/locales/it.json +184 -1
- package/locales/ja.json +184 -1
- package/locales/ka.json +184 -1
- package/locales/kk.json +184 -1
- package/locales/km.json +184 -1
- package/locales/kn.json +184 -1
- package/locales/ko.json +184 -1
- package/locales/ky.json +184 -1
- package/locales/lo.json +184 -1
- package/locales/lt.json +184 -1
- package/locales/lv.json +184 -1
- package/locales/mk.json +184 -1
- package/locales/ml.json +184 -1
- package/locales/mn.json +184 -1
- package/locales/mr.json +184 -1
- package/locales/ms.json +184 -1
- package/locales/my.json +184 -1
- package/locales/ne.json +184 -1
- package/locales/nl.json +184 -1
- package/locales/no.json +184 -1
- package/locales/or.json +184 -1
- package/locales/pa.json +184 -1
- package/locales/pl.json +184 -1
- package/locales/pt-PT.json +184 -1
- package/locales/pt.json +184 -1
- package/locales/ro.json +184 -1
- package/locales/ru.json +184 -1
- package/locales/si.json +184 -1
- package/locales/sk.json +184 -1
- package/locales/sl.json +184 -1
- package/locales/sq.json +184 -1
- package/locales/sr-Latn.json +184 -1
- package/locales/sr.json +184 -1
- package/locales/sv.json +184 -1
- package/locales/sw.json +184 -1
- package/locales/ta.json +184 -1
- package/locales/te.json +184 -1
- package/locales/th.json +184 -1
- package/locales/tr.json +184 -1
- package/locales/uk.json +184 -1
- package/locales/ur.json +184 -1
- package/locales/uz.json +184 -1
- package/locales/vi.json +184 -1
- package/locales/zh-HK.json +184 -1
- package/locales/zh-TW.json +184 -1
- package/locales/zh.json +184 -1
- package/locales/zu.json +184 -1
- package/models/cpu_profile/CPUProfileDataModel.js +10 -10
- package/models/cpu_profile/CPUProfileDataModel.js.map +1 -1
- package/models/trace/LanternComputationData.js.map +1 -1
- package/models/trace/ModelImpl.d.ts +1 -0
- package/models/trace/ModelImpl.js +1 -0
- package/models/trace/ModelImpl.js.map +1 -1
- package/models/trace/Processor.js +16 -11
- package/models/trace/Processor.js.map +1 -1
- package/models/trace/extras/FetchNodes.d.ts +1 -1
- package/models/trace/extras/FetchNodes.js +3 -3
- package/models/trace/extras/FetchNodes.js.map +1 -1
- package/models/trace/extras/ScriptDuplication.d.ts +34 -0
- package/models/trace/extras/ScriptDuplication.js +178 -0
- package/models/trace/extras/ScriptDuplication.js.map +1 -0
- package/models/trace/extras/StackTraceForEvent.js +25 -44
- package/models/trace/extras/StackTraceForEvent.js.map +1 -1
- package/models/trace/extras/ThirdParties.js +1 -0
- package/models/trace/extras/ThirdParties.js.map +1 -1
- package/models/trace/extras/TraceTree.d.ts +5 -2
- package/models/trace/extras/TraceTree.js +47 -17
- package/models/trace/extras/TraceTree.js.map +1 -1
- package/models/trace/extras/extras-tsconfig.json +1 -1
- package/models/trace/extras/extras.d.ts +1 -0
- package/models/trace/extras/extras.js +1 -0
- package/models/trace/extras/extras.js.map +1 -1
- package/models/trace/handlers/AnimationFramesHandler.js.map +1 -1
- package/models/trace/handlers/AsyncJSCallsHandler.js.map +1 -1
- package/models/trace/handlers/AuctionWorkletsHandler.js.map +1 -1
- package/models/trace/handlers/ExtensionTraceDataHandler.d.ts +1 -1
- package/models/trace/handlers/ExtensionTraceDataHandler.js +2 -1
- package/models/trace/handlers/ExtensionTraceDataHandler.js.map +1 -1
- package/models/trace/handlers/FramesHandler.js.map +1 -1
- package/models/trace/handlers/ImagePaintingHandler.js +1 -1
- package/models/trace/handlers/ImagePaintingHandler.js.map +1 -1
- package/models/trace/handlers/InitiatorsHandler.js.map +1 -1
- package/models/trace/handlers/InvalidationsHandler.js.map +1 -1
- package/models/trace/handlers/LayoutShiftsHandler.js.map +1 -1
- package/models/trace/handlers/MetaHandler.d.ts +2 -2
- package/models/trace/handlers/MetaHandler.js +4 -6
- package/models/trace/handlers/MetaHandler.js.map +1 -1
- package/models/trace/handlers/ModelHandlers.d.ts +1 -0
- package/models/trace/handlers/ModelHandlers.js +1 -0
- package/models/trace/handlers/ModelHandlers.js.map +1 -1
- package/models/trace/handlers/NetworkRequestsHandler.d.ts +9 -0
- package/models/trace/handlers/NetworkRequestsHandler.js +6 -6
- package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -1
- package/models/trace/handlers/PageLoadMetricsHandler.js +1 -1
- package/models/trace/handlers/PageLoadMetricsHandler.js.map +1 -1
- package/models/trace/handlers/RendererHandler.js +3 -4
- package/models/trace/handlers/RendererHandler.js.map +1 -1
- package/models/trace/handlers/ScriptsHandler.d.ts +22 -0
- package/models/trace/handlers/ScriptsHandler.js +116 -0
- package/models/trace/handlers/ScriptsHandler.js.map +1 -0
- package/models/trace/handlers/UserTimingsHandler.d.ts +5 -0
- package/models/trace/handlers/UserTimingsHandler.js +16 -0
- package/models/trace/handlers/UserTimingsHandler.js.map +1 -1
- package/models/trace/handlers/WorkersHandler.js.map +1 -1
- package/models/trace/handlers/handlers-tsconfig.json +1 -0
- package/models/trace/handlers/helpers.d.ts +5 -1
- package/models/trace/handlers/helpers.js +28 -4
- package/models/trace/handlers/helpers.js.map +1 -1
- package/models/trace/helpers/Network.d.ts +1 -0
- package/models/trace/helpers/Network.js +8 -3
- package/models/trace/helpers/Network.js.map +1 -1
- package/models/trace/helpers/SamplesIntegrator.d.ts +8 -1
- package/models/trace/helpers/SamplesIntegrator.js +42 -2
- package/models/trace/helpers/SamplesIntegrator.js.map +1 -1
- package/models/trace/helpers/Timing.js.map +1 -1
- package/models/trace/helpers/Trace.d.ts +7 -10
- package/models/trace/helpers/Trace.js +25 -10
- package/models/trace/helpers/Trace.js.map +1 -1
- package/models/trace/insights/CLSCulprits.d.ts +12 -12
- package/models/trace/insights/CLSCulprits.js +15 -4
- package/models/trace/insights/CLSCulprits.js.map +1 -1
- package/models/trace/insights/Common.d.ts +7 -1
- package/models/trace/insights/Common.js +9 -3
- package/models/trace/insights/Common.js.map +1 -1
- package/models/trace/insights/DOMSize.d.ts +8 -8
- package/models/trace/insights/DOMSize.js +2 -1
- package/models/trace/insights/DOMSize.js.map +1 -1
- package/models/trace/insights/DocumentLatency.d.ts +11 -11
- package/models/trace/insights/DocumentLatency.js +2 -1
- package/models/trace/insights/DocumentLatency.js.map +1 -1
- package/models/trace/insights/DuplicateJavaScript.d.ts +18 -0
- package/models/trace/insights/DuplicateJavaScript.js +49 -0
- package/models/trace/insights/DuplicateJavaScript.js.map +1 -0
- package/models/trace/insights/FontDisplay.d.ts +4 -4
- package/models/trace/insights/FontDisplay.js +2 -1
- package/models/trace/insights/FontDisplay.js.map +1 -1
- package/models/trace/insights/ForcedReflow.d.ts +5 -5
- package/models/trace/insights/ForcedReflow.js +4 -1
- package/models/trace/insights/ForcedReflow.js.map +1 -1
- package/models/trace/insights/ImageDelivery.d.ts +19 -15
- package/models/trace/insights/ImageDelivery.js +26 -20
- package/models/trace/insights/ImageDelivery.js.map +1 -1
- package/models/trace/insights/InteractionToNextPaint.d.ts +8 -8
- package/models/trace/insights/InteractionToNextPaint.js +3 -2
- package/models/trace/insights/InteractionToNextPaint.js.map +1 -1
- package/models/trace/insights/LCPDiscovery.d.ts +9 -9
- package/models/trace/insights/LCPDiscovery.js +6 -3
- package/models/trace/insights/LCPDiscovery.js.map +1 -1
- package/models/trace/insights/LCPPhases.d.ts +15 -10
- package/models/trace/insights/LCPPhases.js +11 -4
- package/models/trace/insights/LCPPhases.js.map +1 -1
- package/models/trace/insights/Models.d.ts +2 -1
- package/models/trace/insights/Models.js +2 -1
- package/models/trace/insights/Models.js.map +1 -1
- package/models/trace/insights/NetworkDependencyTree.d.ts +33 -0
- package/models/trace/insights/NetworkDependencyTree.js +141 -0
- package/models/trace/insights/NetworkDependencyTree.js.map +1 -0
- package/models/trace/insights/RenderBlocking.d.ts +5 -5
- package/models/trace/insights/RenderBlocking.js +2 -1
- package/models/trace/insights/RenderBlocking.js.map +1 -1
- package/models/trace/insights/SlowCSSSelector.d.ts +8 -8
- package/models/trace/insights/SlowCSSSelector.js +4 -2
- package/models/trace/insights/SlowCSSSelector.js.map +1 -1
- package/models/trace/insights/ThirdParties.d.ts +6 -6
- package/models/trace/insights/ThirdParties.js +8 -5
- package/models/trace/insights/ThirdParties.js.map +1 -1
- package/models/trace/insights/Viewport.d.ts +2 -2
- package/models/trace/insights/Viewport.js +2 -1
- package/models/trace/insights/Viewport.js.map +1 -1
- package/models/trace/insights/insights-tsconfig.json +2 -1
- package/models/trace/insights/types.d.ts +25 -3
- package/models/trace/insights/types.js.map +1 -1
- package/models/trace/lantern/core/NetworkAnalyzer.d.ts +2 -2
- package/models/trace/lantern/core/NetworkAnalyzer.js +2 -2
- package/models/trace/lantern/core/NetworkAnalyzer.js.map +1 -1
- package/models/trace/lantern/graph/BaseNode.d.ts +1 -1
- package/models/trace/lantern/graph/BaseNode.js.map +1 -1
- package/models/trace/lantern/graph/CPUNode.js +1 -1
- package/models/trace/lantern/graph/CPUNode.js.map +1 -1
- package/models/trace/lantern/graph/NetworkNode.js +1 -1
- package/models/trace/lantern/graph/NetworkNode.js.map +1 -1
- package/models/trace/lantern/graph/PageDependencyGraph.d.ts +2 -2
- package/models/trace/lantern/graph/PageDependencyGraph.js.map +1 -1
- package/models/trace/lantern/metrics/Metric.js.map +1 -1
- package/models/trace/lantern/metrics/TotalBlockingTime.d.ts +2 -2
- package/models/trace/lantern/metrics/TotalBlockingTime.js.map +1 -1
- package/models/trace/lantern/types/Lantern.d.ts +2 -2
- package/models/trace/lantern/types/Lantern.js.map +1 -1
- package/models/trace/trace-tsconfig.json +3 -3
- package/models/trace/trace.d.ts +1 -2
- package/models/trace/trace.js +1 -2
- package/models/trace/trace.js.map +1 -1
- package/models/trace/types/Configuration.d.ts +10 -0
- package/models/trace/types/Configuration.js.map +1 -1
- package/models/trace/types/Extensions.d.ts +1 -1
- package/models/trace/types/Extensions.js.map +1 -1
- package/models/trace/types/TraceEvents.d.ts +87 -4
- package/models/trace/types/TraceEvents.js +20 -0
- package/models/trace/types/TraceEvents.js.map +1 -1
- package/package.json +1 -1
- package/test/test-trace-engine.mjs +3 -2
- package/models/trace/extras/TimelineJSProfile.d.ts +0 -13
- package/models/trace/extras/TimelineJSProfile.js +0 -60
- package/models/trace/extras/TimelineJSProfile.js.map +0 -1
- package/models/trace/insights/LongCriticalNetworkTree.d.ts +0 -22
- package/models/trace/insights/LongCriticalNetworkTree.js +0 -40
- package/models/trace/insights/LongCriticalNetworkTree.js.map +0 -1
- package/models/trace/root-causes/LayoutShift.d.ts +0 -125
- package/models/trace/root-causes/LayoutShift.js +0 -519
- package/models/trace/root-causes/LayoutShift.js.map +0 -1
- package/models/trace/root-causes/RootCauses.d.ts +0 -15
- package/models/trace/root-causes/RootCauses.js +0 -12
- package/models/trace/root-causes/RootCauses.js.map +0 -1
- package/models/trace/root-causes/bundle-tsconfig.json +0 -1
- package/models/trace/root-causes/devtools_entrypoint-bundle-typescript-tsconfig.json +0 -43
- package/models/trace/root-causes/root-causes-tsconfig.json +0 -56
- package/models/trace/root-causes/root-causes.d.ts +0 -1
- package/models/trace/root-causes/root-causes.js +0 -5
- package/models/trace/root-causes/root-causes.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LanternComputationData.js","sourceRoot":"","sources":["../../../../../../front_end/models/trace/LanternComputationData.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Protocol from '../../generated/protocol.js';\n\nimport * as Handlers from './handlers/handlers.js';\nimport * as Lantern from './lantern/lantern.js';\nimport type * as Types from './types/types.js';\n\ntype NetworkRequest = Lantern.Types.NetworkRequest<Types.Events.SyntheticNetworkRequest>;\n\nfunction createProcessedNavigation(parsedTrace: Handlers.Types.ParsedTrace, frameId: string, navigationId: string):\n Lantern.Types.Simulation.ProcessedNavigation {\n const scoresByNav = parsedTrace.PageLoadMetrics.metricScoresByFrameId.get(frameId);\n if (!scoresByNav) {\n throw new Lantern.Core.LanternError('missing metric scores for frame');\n }\n\n const scores = scoresByNav.get(navigationId);\n if (!scores) {\n throw new Lantern.Core.LanternError('missing metric scores for specified navigation');\n }\n\n const getTimestampOrUndefined =\n (metric: Handlers.ModelHandlers.PageLoadMetrics.MetricName): Types.Timing.Micro|undefined => {\n const metricScore = scores.get(metric);\n if (!metricScore?.event) {\n return;\n }\n return metricScore.event.ts;\n };\n const getTimestamp = (metric: Handlers.ModelHandlers.PageLoadMetrics.MetricName): Types.Timing.Micro => {\n const metricScore = scores.get(metric);\n if (!metricScore?.event) {\n throw new Lantern.Core.LanternError(`missing metric: ${metric}`);\n }\n return metricScore.event.ts;\n };\n return {\n timestamps: {\n firstContentfulPaint: getTimestamp(Handlers.ModelHandlers.PageLoadMetrics.MetricName.FCP),\n largestContentfulPaint: getTimestampOrUndefined(Handlers.ModelHandlers.PageLoadMetrics.MetricName.LCP),\n },\n };\n}\n\nfunction createParsedUrl(url: URL|string): Lantern.Types.ParsedURL {\n if (typeof url === 'string') {\n url = new URL(url);\n }\n return {\n scheme: url.protocol.split(':')[0],\n // Intentional, DevTools uses different terminology\n host: url.hostname,\n securityOrigin: url.origin,\n };\n}\n\n/**\n * Returns a map of `pid` -> `tid[]`.\n */\nfunction findWorkerThreads(trace: Lantern.Types.Trace): Map<number, number[]> {\n // TODO: WorkersHandler in Trace Engine needs to be updated to also include `pid` (only had `tid`).\n const workerThreads = new Map();\n const workerCreationEvents = ['ServiceWorker thread', 'DedicatedWorker thread'];\n\n for (const event of trace.traceEvents) {\n if (event.name !== 'thread_name' || !event.args.name) {\n continue;\n }\n if (!workerCreationEvents.includes(event.args.name)) {\n continue;\n }\n\n const tids = workerThreads.get(event.pid);\n if (tids) {\n tids.push(event.tid);\n } else {\n workerThreads.set(event.pid, [event.tid]);\n }\n }\n\n return workerThreads;\n}\n\nfunction createLanternRequest(\n parsedTrace: Readonly<Handlers.Types.ParsedTrace>, workerThreads: Map<number, number[]>,\n request: Types.Events.SyntheticNetworkRequest): NetworkRequest|undefined {\n if (request.args.data.connectionId === undefined || request.args.data.connectionReused === undefined) {\n throw new Lantern.Core.LanternError('Trace is too old');\n }\n\n let url;\n try {\n url = new URL(request.args.data.url);\n } catch {\n return;\n }\n\n const timing = request.args.data.timing ? {\n // These two timings are not included in the trace.\n workerFetchStart: -1,\n workerRespondWithSettled: -1,\n ...request.args.data.timing,\n } :\n undefined;\n\n const networkRequestTime = timing ? timing.requestTime * 1000 : request.args.data.syntheticData.downloadStart / 1000;\n\n let fromWorker = false;\n const tids = workerThreads.get(request.pid);\n if (tids?.includes(request.tid)) {\n fromWorker = true;\n }\n\n // Trace Engine collects worker thread ids in a different manner than `workerThreads` does.\n // AFAIK these should be equivalent, but in case they are not let's also check this for now.\n if (parsedTrace.Workers.workerIdByThread.has(request.tid)) {\n fromWorker = true;\n }\n\n // `initiator` in the trace does not contain the stack trace for JS-initiated\n // requests. Instead, that is stored in the `stackTrace` property of the SyntheticNetworkRequest.\n // There are some minor differences in the fields, accounted for here.\n // Most importantly, there seems to be fewer frames in the trace than the equivalent\n // events over the CDP. This results in less accuracy in determining the initiator request,\n // which means less edges in the graph, which mean worse results.\n // TODO: Should fix in Chromium.\n const initiator: Lantern.Types.NetworkRequest['initiator'] =\n request.args.data.initiator ?? {type: Protocol.Network.InitiatorType.Other};\n if (request.args.data.stackTrace) {\n const callFrames = request.args.data.stackTrace.map(f => {\n return {\n scriptId: String(f.scriptId) as Protocol.Runtime.ScriptId,\n url: f.url,\n lineNumber: f.lineNumber - 1,\n columnNumber: f.columnNumber - 1,\n functionName: f.functionName,\n };\n });\n initiator.stack = {callFrames};\n // Note: there is no `parent` to set ...\n }\n\n let resourceType = request.args.data.resourceType;\n if (request.args.data.initiator?.fetchType === 'xmlhttprequest') {\n // @ts-expect-error yes XHR is a valid ResourceType. TypeScript const enums are so unhelpful.\n resourceType = 'XHR';\n } else if (request.args.data.initiator?.fetchType === 'fetch') {\n // @ts-expect-error yes Fetch is a valid ResourceType. TypeScript const enums are so unhelpful.\n resourceType = 'Fetch';\n }\n\n // TODO: set decodedBodyLength for data urls in Trace Engine.\n let resourceSize = request.args.data.decodedBodyLength ?? 0;\n if (url.protocol === 'data:' && resourceSize === 0) {\n const commaIndex = url.pathname.indexOf(',');\n if (url.pathname.substring(0, commaIndex).includes(';base64')) {\n resourceSize = atob(url.pathname.substring(commaIndex + 1)).length;\n } else {\n resourceSize = url.pathname.length - commaIndex - 1;\n }\n }\n\n return {\n rawRequest: request,\n requestId: request.args.data.requestId,\n connectionId: request.args.data.connectionId,\n connectionReused: request.args.data.connectionReused,\n url: request.args.data.url,\n protocol: request.args.data.protocol,\n parsedURL: createParsedUrl(url),\n documentURL: request.args.data.requestingFrameUrl,\n rendererStartTime: request.ts / 1000,\n networkRequestTime,\n responseHeadersEndTime: request.args.data.syntheticData.downloadStart / 1000,\n networkEndTime: request.args.data.syntheticData.finishTime / 1000,\n transferSize: request.args.data.encodedDataLength,\n resourceSize,\n fromDiskCache: request.args.data.syntheticData.isDiskCached,\n fromMemoryCache: request.args.data.syntheticData.isMemoryCached,\n isLinkPreload: request.args.data.isLinkPreload,\n finished: request.args.data.finished,\n failed: request.args.data.failed,\n statusCode: request.args.data.statusCode,\n initiator,\n timing,\n resourceType,\n mimeType: request.args.data.mimeType,\n priority: request.args.data.priority,\n frameId: request.args.data.frame,\n fromWorker,\n // Set later.\n redirects: undefined,\n redirectSource: undefined,\n redirectDestination: undefined,\n initiatorRequest: undefined,\n };\n}\n\n/**\n * @param request The request to find the initiator of\n */\nfunction chooseInitiatorRequest(request: NetworkRequest, requestsByURL: Map<string, NetworkRequest[]>): NetworkRequest|\n null {\n if (request.redirectSource) {\n return request.redirectSource;\n }\n\n const initiatorURL = Lantern.Graph.PageDependencyGraph.getNetworkInitiators(request)[0];\n let candidates = requestsByURL.get(initiatorURL) || [];\n // The (valid) initiator must come before the initiated request.\n candidates = candidates.filter(c => {\n return c.responseHeadersEndTime <= request.rendererStartTime && c.finished && !c.failed;\n });\n if (candidates.length > 1) {\n // Disambiguate based on prefetch. Prefetch requests have type 'Other' and cannot\n // initiate requests, so we drop them here.\n const nonPrefetchCandidates =\n candidates.filter(cand => cand.resourceType !== Lantern.Types.NetworkRequestTypes.Other);\n if (nonPrefetchCandidates.length) {\n candidates = nonPrefetchCandidates;\n }\n }\n if (candidates.length > 1) {\n // Disambiguate based on frame. It's likely that the initiator comes from the same frame.\n const sameFrameCandidates = candidates.filter(cand => cand.frameId === request.frameId);\n if (sameFrameCandidates.length) {\n candidates = sameFrameCandidates;\n }\n }\n if (candidates.length > 1 && request.initiator.type === 'parser') {\n // Filter to just Documents when initiator type is parser.\n const documentCandidates =\n candidates.filter(cand => cand.resourceType === Lantern.Types.NetworkRequestTypes.Document);\n if (documentCandidates.length) {\n candidates = documentCandidates;\n }\n }\n if (candidates.length > 1) {\n // If all real loads came from successful preloads (url preloaded and\n // loads came from the cache), filter to link rel=preload request(s).\n const linkPreloadCandidates = candidates.filter(c => c.isLinkPreload);\n if (linkPreloadCandidates.length) {\n const nonPreloadCandidates = candidates.filter(c => !c.isLinkPreload);\n const allPreloaded = nonPreloadCandidates.every(c => c.fromDiskCache || c.fromMemoryCache);\n if (nonPreloadCandidates.length && allPreloaded) {\n candidates = linkPreloadCandidates;\n }\n }\n }\n\n // Only return an initiator if the result is unambiguous.\n return candidates.length === 1 ? candidates[0] : null;\n}\n\nfunction linkInitiators(lanternRequests: NetworkRequest[]): void {\n const requestsByURL: Map<string, NetworkRequest[]> = new Map();\n for (const request of lanternRequests) {\n const requests = requestsByURL.get(request.url) || [];\n requests.push(request);\n requestsByURL.set(request.url, requests);\n }\n\n for (const request of lanternRequests) {\n const initiatorRequest = chooseInitiatorRequest(request, requestsByURL);\n if (initiatorRequest) {\n request.initiatorRequest = initiatorRequest;\n }\n }\n}\n\nfunction createNetworkRequests(\n trace: Lantern.Types.Trace, parsedTrace: Handlers.Types.ParsedTrace, startTime = 0,\n endTime = Number.POSITIVE_INFINITY): NetworkRequest[] {\n const workerThreads = findWorkerThreads(trace);\n\n const lanternRequests: NetworkRequest[] = [];\n for (const request of parsedTrace.NetworkRequests.byTime) {\n if (request.ts >= startTime && request.ts < endTime) {\n const lanternRequest = createLanternRequest(parsedTrace, workerThreads, request);\n if (lanternRequest) {\n lanternRequests.push(lanternRequest);\n }\n }\n }\n\n // Trace Engine consolidates all redirects into a single request object, but lantern needs\n // an entry for each redirected request.\n for (const request of [...lanternRequests]) {\n if (!request.rawRequest) {\n continue;\n }\n\n const redirects = request.rawRequest.args.data.redirects;\n if (!redirects.length) {\n continue;\n }\n\n const requestChain = [];\n for (const redirect of redirects) {\n const redirectedRequest = structuredClone(request);\n\n redirectedRequest.networkRequestTime = redirect.ts / 1000;\n redirectedRequest.rendererStartTime = redirectedRequest.networkRequestTime;\n\n redirectedRequest.networkEndTime = (redirect.ts + redirect.dur) / 1000;\n redirectedRequest.responseHeadersEndTime = redirectedRequest.networkEndTime;\n\n redirectedRequest.timing = {\n requestTime: redirectedRequest.networkRequestTime / 1000,\n receiveHeadersStart: redirectedRequest.responseHeadersEndTime,\n receiveHeadersEnd: redirectedRequest.responseHeadersEndTime,\n proxyStart: -1,\n proxyEnd: -1,\n dnsStart: -1,\n dnsEnd: -1,\n connectStart: -1,\n connectEnd: -1,\n sslStart: -1,\n sslEnd: -1,\n sendStart: -1,\n sendEnd: -1,\n workerStart: -1,\n workerReady: -1,\n workerFetchStart: -1,\n workerRespondWithSettled: -1,\n pushStart: -1,\n pushEnd: -1,\n };\n\n redirectedRequest.url = redirect.url;\n redirectedRequest.parsedURL = createParsedUrl(redirect.url);\n // TODO: Trace Engine is not retaining the actual status code.\n redirectedRequest.statusCode = 302;\n redirectedRequest.resourceType = undefined;\n // TODO: Trace Engine is not retaining transfer size of redirected request.\n redirectedRequest.transferSize = 400;\n requestChain.push(redirectedRequest);\n lanternRequests.push(redirectedRequest);\n }\n requestChain.push(request);\n\n for (let i = 0; i < requestChain.length; i++) {\n const request = requestChain[i];\n if (i > 0) {\n request.redirectSource = requestChain[i - 1];\n request.redirects = requestChain.slice(0, i);\n }\n if (i !== requestChain.length - 1) {\n request.redirectDestination = requestChain[i + 1];\n }\n }\n\n // Apply the `:redirect` requestId convention: only redirects[0].requestId is the actual\n // requestId, all the rest have n occurrences of `:redirect` as a suffix.\n for (let i = 1; i < requestChain.length; i++) {\n requestChain[i].requestId = `${requestChain[i - 1].requestId}:redirect`;\n }\n }\n\n linkInitiators(lanternRequests);\n\n // This would already be sorted by rendererStartTime, if not for the redirect unwrapping done\n // above.\n return lanternRequests.sort((a, b) => a.rendererStartTime - b.rendererStartTime);\n}\n\nfunction collectMainThreadEvents(\n trace: Lantern.Types.Trace, parsedTrace: Handlers.Types.ParsedTrace): Lantern.Types.TraceEvent[] {\n const Meta = parsedTrace.Meta;\n const mainFramePids = Meta.mainFrameNavigations.length ? new Set(Meta.mainFrameNavigations.map(nav => nav.pid)) :\n Meta.topLevelRendererIds;\n\n const rendererPidToTid = new Map();\n for (const pid of mainFramePids) {\n const threads = Meta.threadsInProcess.get(pid) ?? [];\n\n let found = false;\n for (const [tid, thread] of threads) {\n if (thread.args.name === 'CrRendererMain') {\n rendererPidToTid.set(pid, tid);\n found = true;\n break;\n }\n }\n\n if (found) {\n continue;\n }\n\n // `CrRendererMain` can be missing if chrome is launched with the `--single-process` flag.\n // In this case, page tasks will be run in the browser thread.\n for (const [tid, thread] of threads) {\n if (thread.args.name === 'CrBrowserMain') {\n rendererPidToTid.set(pid, tid);\n found = true;\n break;\n }\n }\n }\n\n return trace.traceEvents.filter(e => rendererPidToTid.get(e.pid) === e.tid);\n}\n\nfunction createGraph(\n requests: Lantern.Types.NetworkRequest[], trace: Lantern.Types.Trace, parsedTrace: Handlers.Types.ParsedTrace,\n url?: Lantern.Types.Simulation.URL): Lantern.Graph.Node<Types.Events.SyntheticNetworkRequest> {\n const mainThreadEvents = collectMainThreadEvents(trace, parsedTrace);\n\n // url defines the initial request that the Lantern graph starts at (the root node) and the\n // main document request. These are equal if there are no redirects.\n if (!url) {\n url = {\n requestedUrl: requests[0].url,\n mainDocumentUrl: '',\n };\n\n let request = requests[0];\n while (request.redirectDestination) {\n request = request.redirectDestination;\n }\n url.mainDocumentUrl = request.url;\n }\n\n return Lantern.Graph.PageDependencyGraph.createGraph(mainThreadEvents, requests, url);\n}\n\nexport {\n createGraph,\n createNetworkRequests,\n createProcessedNavigation,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"LanternComputationData.js","sourceRoot":"","sources":["../../../../../../front_end/models/trace/LanternComputationData.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Protocol from '../../generated/protocol.js';\n\nimport * as Handlers from './handlers/handlers.js';\nimport * as Lantern from './lantern/lantern.js';\nimport type * as Types from './types/types.js';\n\ntype NetworkRequest = Lantern.Types.NetworkRequest<Types.Events.SyntheticNetworkRequest>;\n\nfunction createProcessedNavigation(parsedTrace: Handlers.Types.ParsedTrace, frameId: string, navigationId: string):\n Lantern.Types.Simulation.ProcessedNavigation {\n const scoresByNav = parsedTrace.PageLoadMetrics.metricScoresByFrameId.get(frameId);\n if (!scoresByNav) {\n throw new Lantern.Core.LanternError('missing metric scores for frame');\n }\n\n const scores = scoresByNav.get(navigationId);\n if (!scores) {\n throw new Lantern.Core.LanternError('missing metric scores for specified navigation');\n }\n\n const getTimestampOrUndefined =\n (metric: Handlers.ModelHandlers.PageLoadMetrics.MetricName): Types.Timing.Micro|undefined => {\n const metricScore = scores.get(metric);\n if (!metricScore?.event) {\n return;\n }\n return metricScore.event.ts;\n };\n const getTimestamp = (metric: Handlers.ModelHandlers.PageLoadMetrics.MetricName): Types.Timing.Micro => {\n const metricScore = scores.get(metric);\n if (!metricScore?.event) {\n throw new Lantern.Core.LanternError(`missing metric: ${metric}`);\n }\n return metricScore.event.ts;\n };\n return {\n timestamps: {\n firstContentfulPaint: getTimestamp(Handlers.ModelHandlers.PageLoadMetrics.MetricName.FCP),\n largestContentfulPaint: getTimestampOrUndefined(Handlers.ModelHandlers.PageLoadMetrics.MetricName.LCP),\n },\n };\n}\n\nfunction createParsedUrl(url: URL|string): Lantern.Types.ParsedURL {\n if (typeof url === 'string') {\n url = new URL(url);\n }\n return {\n scheme: url.protocol.split(':')[0],\n // Intentional, DevTools uses different terminology\n host: url.hostname,\n securityOrigin: url.origin,\n };\n}\n\n/**\n * Returns a map of `pid` -> `tid[]`.\n */\nfunction findWorkerThreads(trace: Lantern.Types.Trace): Map<number, number[]> {\n // TODO: WorkersHandler in Trace Engine needs to be updated to also include `pid` (only had `tid`).\n const workerThreads = new Map();\n const workerCreationEvents = ['ServiceWorker thread', 'DedicatedWorker thread'];\n\n for (const event of trace.traceEvents) {\n if (event.name !== 'thread_name' || !event.args.name) {\n continue;\n }\n if (!workerCreationEvents.includes(event.args.name)) {\n continue;\n }\n\n const tids = workerThreads.get(event.pid);\n if (tids) {\n tids.push(event.tid);\n } else {\n workerThreads.set(event.pid, [event.tid]);\n }\n }\n\n return workerThreads;\n}\n\nfunction createLanternRequest(\n parsedTrace: Readonly<Handlers.Types.ParsedTrace>, workerThreads: Map<number, number[]>,\n request: Types.Events.SyntheticNetworkRequest): NetworkRequest|undefined {\n if (request.args.data.connectionId === undefined || request.args.data.connectionReused === undefined) {\n throw new Lantern.Core.LanternError('Trace is too old');\n }\n\n let url;\n try {\n url = new URL(request.args.data.url);\n } catch {\n return;\n }\n\n const timing = request.args.data.timing ? {\n // These two timings are not included in the trace.\n workerFetchStart: -1,\n workerRespondWithSettled: -1,\n ...request.args.data.timing,\n } :\n undefined;\n\n const networkRequestTime = timing ? timing.requestTime * 1000 : request.args.data.syntheticData.downloadStart / 1000;\n\n let fromWorker = false;\n const tids = workerThreads.get(request.pid);\n if (tids?.includes(request.tid)) {\n fromWorker = true;\n }\n\n // Trace Engine collects worker thread ids in a different manner than `workerThreads` does.\n // AFAIK these should be equivalent, but in case they are not let's also check this for now.\n if (parsedTrace.Workers.workerIdByThread.has(request.tid)) {\n fromWorker = true;\n }\n\n // `initiator` in the trace does not contain the stack trace for JS-initiated\n // requests. Instead, that is stored in the `stackTrace` property of the SyntheticNetworkRequest.\n // There are some minor differences in the fields, accounted for here.\n // Most importantly, there seems to be fewer frames in the trace than the equivalent\n // events over the CDP. This results in less accuracy in determining the initiator request,\n // which means less edges in the graph, which mean worse results.\n // TODO: Should fix in Chromium.\n const initiator: Lantern.Types.NetworkRequest['initiator'] =\n request.args.data.initiator ?? {type: Protocol.Network.InitiatorType.Other};\n if (request.args.data.stackTrace) {\n const callFrames = request.args.data.stackTrace.map(f => {\n return {\n scriptId: String(f.scriptId) as Protocol.Runtime.ScriptId,\n url: f.url,\n lineNumber: f.lineNumber - 1,\n columnNumber: f.columnNumber - 1,\n functionName: f.functionName,\n };\n });\n initiator.stack = {callFrames};\n // Note: there is no `parent` to set ...\n }\n\n let resourceType = request.args.data.resourceType;\n if (request.args.data.initiator?.fetchType === 'xmlhttprequest') {\n // @ts-expect-error yes XHR is a valid ResourceType. TypeScript const enums are so unhelpful.\n resourceType = 'XHR';\n } else if (request.args.data.initiator?.fetchType === 'fetch') {\n // @ts-expect-error yes Fetch is a valid ResourceType. TypeScript const enums are so unhelpful.\n resourceType = 'Fetch';\n }\n\n // TODO: set decodedBodyLength for data urls in Trace Engine.\n let resourceSize = request.args.data.decodedBodyLength ?? 0;\n if (url.protocol === 'data:' && resourceSize === 0) {\n const commaIndex = url.pathname.indexOf(',');\n if (url.pathname.substring(0, commaIndex).includes(';base64')) {\n resourceSize = atob(url.pathname.substring(commaIndex + 1)).length;\n } else {\n resourceSize = url.pathname.length - commaIndex - 1;\n }\n }\n\n return {\n rawRequest: request,\n requestId: request.args.data.requestId,\n connectionId: request.args.data.connectionId,\n connectionReused: request.args.data.connectionReused,\n url: request.args.data.url,\n protocol: request.args.data.protocol,\n parsedURL: createParsedUrl(url),\n documentURL: request.args.data.requestingFrameUrl,\n rendererStartTime: request.ts / 1000,\n networkRequestTime,\n responseHeadersEndTime: request.args.data.syntheticData.downloadStart / 1000,\n networkEndTime: request.args.data.syntheticData.finishTime / 1000,\n transferSize: request.args.data.encodedDataLength,\n resourceSize,\n fromDiskCache: request.args.data.syntheticData.isDiskCached,\n fromMemoryCache: request.args.data.syntheticData.isMemoryCached,\n isLinkPreload: request.args.data.isLinkPreload,\n finished: request.args.data.finished,\n failed: request.args.data.failed,\n statusCode: request.args.data.statusCode,\n initiator,\n timing,\n resourceType,\n mimeType: request.args.data.mimeType,\n priority: request.args.data.priority,\n frameId: request.args.data.frame,\n fromWorker,\n // Set later.\n redirects: undefined,\n redirectSource: undefined,\n redirectDestination: undefined,\n initiatorRequest: undefined,\n };\n}\n\n/**\n * @param request The request to find the initiator of\n */\nfunction chooseInitiatorRequest(request: NetworkRequest, requestsByURL: Map<string, NetworkRequest[]>): NetworkRequest|\n null {\n if (request.redirectSource) {\n return request.redirectSource;\n }\n\n const initiatorURL = Lantern.Graph.PageDependencyGraph.getNetworkInitiators(request)[0];\n let candidates = requestsByURL.get(initiatorURL) || [];\n // The (valid) initiator must come before the initiated request.\n candidates = candidates.filter(c => {\n return c.responseHeadersEndTime <= request.rendererStartTime && c.finished && !c.failed;\n });\n if (candidates.length > 1) {\n // Disambiguate based on prefetch. Prefetch requests have type 'Other' and cannot\n // initiate requests, so we drop them here.\n const nonPrefetchCandidates =\n candidates.filter(cand => cand.resourceType !== Lantern.Types.NetworkRequestTypes.Other);\n if (nonPrefetchCandidates.length) {\n candidates = nonPrefetchCandidates;\n }\n }\n if (candidates.length > 1) {\n // Disambiguate based on frame. It's likely that the initiator comes from the same frame.\n const sameFrameCandidates = candidates.filter(cand => cand.frameId === request.frameId);\n if (sameFrameCandidates.length) {\n candidates = sameFrameCandidates;\n }\n }\n if (candidates.length > 1 && request.initiator.type === 'parser') {\n // Filter to just Documents when initiator type is parser.\n const documentCandidates =\n candidates.filter(cand => cand.resourceType === Lantern.Types.NetworkRequestTypes.Document);\n if (documentCandidates.length) {\n candidates = documentCandidates;\n }\n }\n if (candidates.length > 1) {\n // If all real loads came from successful preloads (url preloaded and\n // loads came from the cache), filter to link rel=preload request(s).\n const linkPreloadCandidates = candidates.filter(c => c.isLinkPreload);\n if (linkPreloadCandidates.length) {\n const nonPreloadCandidates = candidates.filter(c => !c.isLinkPreload);\n const allPreloaded = nonPreloadCandidates.every(c => c.fromDiskCache || c.fromMemoryCache);\n if (nonPreloadCandidates.length && allPreloaded) {\n candidates = linkPreloadCandidates;\n }\n }\n }\n\n // Only return an initiator if the result is unambiguous.\n return candidates.length === 1 ? candidates[0] : null;\n}\n\nfunction linkInitiators(lanternRequests: NetworkRequest[]): void {\n const requestsByURL = new Map<string, NetworkRequest[]>();\n for (const request of lanternRequests) {\n const requests = requestsByURL.get(request.url) || [];\n requests.push(request);\n requestsByURL.set(request.url, requests);\n }\n\n for (const request of lanternRequests) {\n const initiatorRequest = chooseInitiatorRequest(request, requestsByURL);\n if (initiatorRequest) {\n request.initiatorRequest = initiatorRequest;\n }\n }\n}\n\nfunction createNetworkRequests(\n trace: Lantern.Types.Trace, parsedTrace: Handlers.Types.ParsedTrace, startTime = 0,\n endTime = Number.POSITIVE_INFINITY): NetworkRequest[] {\n const workerThreads = findWorkerThreads(trace);\n\n const lanternRequests: NetworkRequest[] = [];\n for (const request of parsedTrace.NetworkRequests.byTime) {\n if (request.ts >= startTime && request.ts < endTime) {\n const lanternRequest = createLanternRequest(parsedTrace, workerThreads, request);\n if (lanternRequest) {\n lanternRequests.push(lanternRequest);\n }\n }\n }\n\n // Trace Engine consolidates all redirects into a single request object, but lantern needs\n // an entry for each redirected request.\n for (const request of [...lanternRequests]) {\n if (!request.rawRequest) {\n continue;\n }\n\n const redirects = request.rawRequest.args.data.redirects;\n if (!redirects.length) {\n continue;\n }\n\n const requestChain = [];\n for (const redirect of redirects) {\n const redirectedRequest = structuredClone(request);\n\n redirectedRequest.networkRequestTime = redirect.ts / 1000;\n redirectedRequest.rendererStartTime = redirectedRequest.networkRequestTime;\n\n redirectedRequest.networkEndTime = (redirect.ts + redirect.dur) / 1000;\n redirectedRequest.responseHeadersEndTime = redirectedRequest.networkEndTime;\n\n redirectedRequest.timing = {\n requestTime: redirectedRequest.networkRequestTime / 1000,\n receiveHeadersStart: redirectedRequest.responseHeadersEndTime,\n receiveHeadersEnd: redirectedRequest.responseHeadersEndTime,\n proxyStart: -1,\n proxyEnd: -1,\n dnsStart: -1,\n dnsEnd: -1,\n connectStart: -1,\n connectEnd: -1,\n sslStart: -1,\n sslEnd: -1,\n sendStart: -1,\n sendEnd: -1,\n workerStart: -1,\n workerReady: -1,\n workerFetchStart: -1,\n workerRespondWithSettled: -1,\n pushStart: -1,\n pushEnd: -1,\n };\n\n redirectedRequest.url = redirect.url;\n redirectedRequest.parsedURL = createParsedUrl(redirect.url);\n // TODO: Trace Engine is not retaining the actual status code.\n redirectedRequest.statusCode = 302;\n redirectedRequest.resourceType = undefined;\n // TODO: Trace Engine is not retaining transfer size of redirected request.\n redirectedRequest.transferSize = 400;\n requestChain.push(redirectedRequest);\n lanternRequests.push(redirectedRequest);\n }\n requestChain.push(request);\n\n for (let i = 0; i < requestChain.length; i++) {\n const request = requestChain[i];\n if (i > 0) {\n request.redirectSource = requestChain[i - 1];\n request.redirects = requestChain.slice(0, i);\n }\n if (i !== requestChain.length - 1) {\n request.redirectDestination = requestChain[i + 1];\n }\n }\n\n // Apply the `:redirect` requestId convention: only redirects[0].requestId is the actual\n // requestId, all the rest have n occurrences of `:redirect` as a suffix.\n for (let i = 1; i < requestChain.length; i++) {\n requestChain[i].requestId = `${requestChain[i - 1].requestId}:redirect`;\n }\n }\n\n linkInitiators(lanternRequests);\n\n // This would already be sorted by rendererStartTime, if not for the redirect unwrapping done\n // above.\n return lanternRequests.sort((a, b) => a.rendererStartTime - b.rendererStartTime);\n}\n\nfunction collectMainThreadEvents(\n trace: Lantern.Types.Trace, parsedTrace: Handlers.Types.ParsedTrace): Lantern.Types.TraceEvent[] {\n const Meta = parsedTrace.Meta;\n const mainFramePids = Meta.mainFrameNavigations.length ? new Set(Meta.mainFrameNavigations.map(nav => nav.pid)) :\n Meta.topLevelRendererIds;\n\n const rendererPidToTid = new Map();\n for (const pid of mainFramePids) {\n const threads = Meta.threadsInProcess.get(pid) ?? [];\n\n let found = false;\n for (const [tid, thread] of threads) {\n if (thread.args.name === 'CrRendererMain') {\n rendererPidToTid.set(pid, tid);\n found = true;\n break;\n }\n }\n\n if (found) {\n continue;\n }\n\n // `CrRendererMain` can be missing if chrome is launched with the `--single-process` flag.\n // In this case, page tasks will be run in the browser thread.\n for (const [tid, thread] of threads) {\n if (thread.args.name === 'CrBrowserMain') {\n rendererPidToTid.set(pid, tid);\n found = true;\n break;\n }\n }\n }\n\n return trace.traceEvents.filter(e => rendererPidToTid.get(e.pid) === e.tid);\n}\n\nfunction createGraph(\n requests: Lantern.Types.NetworkRequest[], trace: Lantern.Types.Trace, parsedTrace: Handlers.Types.ParsedTrace,\n url?: Lantern.Types.Simulation.URL): Lantern.Graph.Node<Types.Events.SyntheticNetworkRequest> {\n const mainThreadEvents = collectMainThreadEvents(trace, parsedTrace);\n\n // url defines the initial request that the Lantern graph starts at (the root node) and the\n // main document request. These are equal if there are no redirects.\n if (!url) {\n url = {\n requestedUrl: requests[0].url,\n mainDocumentUrl: '',\n };\n\n let request = requests[0];\n while (request.redirectDestination) {\n request = request.redirectDestination;\n }\n url.mainDocumentUrl = request.url;\n }\n\n return Lantern.Graph.PageDependencyGraph.createGraph(mainThreadEvents, requests, url);\n}\n\nexport {\n createGraph,\n createNetworkRequests,\n createProcessedNavigation,\n};\n"]}
|
|
@@ -5,6 +5,7 @@ import * as Types from './types/types.js';
|
|
|
5
5
|
export interface ParseConfig {
|
|
6
6
|
metadata?: Types.File.MetaData;
|
|
7
7
|
isFreshRecording?: boolean;
|
|
8
|
+
resolveSourceMap?: Types.Configuration.ParseOptions['resolveSourceMap'];
|
|
8
9
|
}
|
|
9
10
|
/**
|
|
10
11
|
* The Model is responsible for parsing arrays of raw trace events and storing the
|
|
@@ -95,6 +95,7 @@ export class Model extends EventTarget {
|
|
|
95
95
|
isFreshRecording,
|
|
96
96
|
isCPUProfile,
|
|
97
97
|
metadata,
|
|
98
|
+
resolveSourceMap: config?.resolveSourceMap,
|
|
98
99
|
});
|
|
99
100
|
this.#storeParsedFileData(file, this.#processor.parsedTrace, this.#processor.insights);
|
|
100
101
|
// We only push the file onto this.#traces here once we know it's valid
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModelImpl.js","sourceRoot":"","sources":["../../../../../../front_end/models/trace/ModelImpl.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../core/platform/platform.js';\n\nimport * as Handlers from './handlers/handlers.js';\nimport * as Helpers from './helpers/helpers.js';\nimport type * as Insights from './insights/insights.js';\nimport {TraceParseProgressEvent, TraceProcessor} from './Processor.js';\nimport * as Types from './types/types.js';\n\n// Note: this model is implemented in a way that can support multiple trace\n// processors. Currently there is only one implemented, but you will see\n// references to \"processors\" plural because it can easily be extended in the future.\n\nexport interface ParseConfig {\n metadata?: Types.File.MetaData;\n isFreshRecording?: boolean;\n}\n\n/**\n * The Model is responsible for parsing arrays of raw trace events and storing the\n * resulting data. It can store multiple traces at once, and can return the data for\n * any of them.\n *\n * Most uses of this class should be through `createWithAllHandlers`, but\n * `createWithSubsetOfHandlers` can be used to run just some handlers.\n **/\nexport class Model extends EventTarget {\n readonly #traces: ParsedTraceFile[] = [];\n readonly #syntheticEventsManagerByTrace: Helpers.SyntheticEvents.SyntheticEventsManager[] = [];\n readonly #nextNumberByDomain = new Map<string, number>();\n\n readonly #recordingsAvailable: string[] = [];\n #lastRecordingIndex = 0;\n #processor: TraceProcessor;\n #config: Types.Configuration.Configuration = Types.Configuration.defaults();\n\n static createWithAllHandlers(config?: Types.Configuration.Configuration): Model {\n return new Model(Handlers.ModelHandlers, config);\n }\n\n /**\n * Runs only the provided handlers.\n *\n * Callers must ensure they are providing all dependant handlers (although Meta is included automatically),\n * and must know that the result of `.parsedTrace` will be limited to the handlers provided, even though\n * the type won't reflect that.\n */\n static createWithSubsetOfHandlers(\n traceHandlers: Partial<Handlers.Types.Handlers>, config?: Types.Configuration.Configuration): Model {\n return new Model(traceHandlers as Handlers.Types.Handlers, config);\n }\n\n constructor(handlers: Handlers.Types.Handlers, config?: Types.Configuration.Configuration) {\n super();\n if (config) {\n this.#config = config;\n }\n this.#processor = new TraceProcessor(handlers, this.#config);\n }\n\n /**\n * Parses an array of trace events into a structured object containing all the\n * information parsed by the trace handlers.\n * You can `await` this function to pause execution until parsing is complete,\n * or instead rely on the `ModuleUpdateEvent` that is dispatched when the\n * parsing is finished.\n *\n * Once parsed, you then have to call the `parsedTrace` method, providing an\n * index of the trace you want to have the data for. This is because any model\n * can store a number of traces. Each trace is given an index, which starts at 0\n * and increments by one as a new trace is parsed.\n *\n * @example\n * // Awaiting the parse method() to block until parsing complete\n * await this.traceModel.parse(events);\n * const data = this.traceModel.parsedTrace(0)\n *\n * @example\n * // Using an event listener to be notified when tracing is complete.\n * this.traceModel.addEventListener(Trace.ModelUpdateEvent.eventName, (event) => {\n * if(event.data.data === 'done') {\n * // trace complete\n * const data = this.traceModel.parsedTrace(0);\n * }\n * });\n * void this.traceModel.parse(events);\n **/\n async parse(traceEvents: readonly Types.Events.Event[], config?: ParseConfig): Promise<void> {\n const metadata = config?.metadata || {};\n const isFreshRecording = config?.isFreshRecording || false;\n const isCPUProfile = metadata?.dataOrigin === Types.File.DataOrigin.CPU_PROFILE;\n // During parsing, periodically update any listeners on each processors'\n // progress (if they have any updates).\n const onTraceUpdate = (event: Event): void => {\n const {data} = event as TraceParseProgressEvent;\n this.dispatchEvent(new ModelUpdateEvent({type: ModelUpdateType.PROGRESS_UPDATE, data}));\n };\n\n this.#processor.addEventListener(TraceParseProgressEvent.eventName, onTraceUpdate);\n\n // Create a parsed trace file. It will be populated with data from the processor.\n const file: ParsedTraceFile = {\n traceEvents,\n metadata,\n parsedTrace: null,\n traceInsights: null,\n };\n\n try {\n // Wait for all outstanding promises before finishing the async execution,\n // but perform all tasks in parallel.\n const syntheticEventsManager = Helpers.SyntheticEvents.SyntheticEventsManager.createAndActivate(traceEvents);\n await this.#processor.parse(traceEvents, {\n isFreshRecording,\n isCPUProfile,\n metadata,\n });\n this.#storeParsedFileData(file, this.#processor.parsedTrace, this.#processor.insights);\n // We only push the file onto this.#traces here once we know it's valid\n // and there's been no errors in the parsing.\n this.#traces.push(file);\n this.#syntheticEventsManagerByTrace.push(syntheticEventsManager);\n } catch (e) {\n throw e;\n } finally {\n // All processors have finished parsing, no more updates are expected.\n this.#processor.removeEventListener(TraceParseProgressEvent.eventName, onTraceUpdate);\n // Finally, update any listeners that all processors are 'done'.\n this.dispatchEvent(new ModelUpdateEvent({type: ModelUpdateType.COMPLETE, data: 'done'}));\n }\n }\n\n #storeParsedFileData(\n file: ParsedTraceFile, data: Handlers.Types.ParsedTrace|null,\n insights: Insights.Types.TraceInsightSets|null): void {\n file.parsedTrace = data;\n file.traceInsights = insights;\n this.#lastRecordingIndex++;\n let recordingName = `Trace ${this.#lastRecordingIndex}`;\n let origin: string|null = null;\n if (file.parsedTrace) {\n origin = Helpers.Trace.extractOriginFromTrace(file.parsedTrace.Meta.mainFrameURL);\n if (origin) {\n const nextSequenceForDomain = Platform.MapUtilities.getWithDefault(this.#nextNumberByDomain, origin, () => 1);\n recordingName = `${origin} (${nextSequenceForDomain})`;\n this.#nextNumberByDomain.set(origin, nextSequenceForDomain + 1);\n }\n }\n this.#recordingsAvailable.push(recordingName);\n }\n\n lastTraceIndex(): number {\n return this.size() - 1;\n }\n\n /**\n * Returns the parsed trace data indexed by the order in which it was stored.\n * If no index is given, the last stored parsed data is returned.\n */\n parsedTrace(index: number = this.#traces.length - 1): Handlers.Types.ParsedTrace|null {\n return this.#traces.at(index)?.parsedTrace ?? null;\n }\n\n traceInsights(index: number = this.#traces.length - 1): Insights.Types.TraceInsightSets|null {\n return this.#traces.at(index)?.traceInsights ?? null;\n }\n\n metadata(index: number = this.#traces.length - 1): Types.File.MetaData|null {\n return this.#traces.at(index)?.metadata ?? null;\n }\n\n overrideModifications(index: number, newModifications: Types.File.Modifications): void {\n if (this.#traces[index]) {\n this.#traces[index].metadata.modifications = newModifications;\n }\n }\n\n rawTraceEvents(index: number = this.#traces.length - 1): readonly Types.Events.Event[]|null {\n return this.#traces.at(index)?.traceEvents ?? null;\n }\n\n syntheticTraceEventsManager(index: number = this.#traces.length - 1): Helpers.SyntheticEvents.SyntheticEventsManager\n |null {\n return this.#syntheticEventsManagerByTrace.at(index) ?? null;\n }\n\n size(): number {\n return this.#traces.length;\n }\n\n deleteTraceByIndex(recordingIndex: number): void {\n this.#traces.splice(recordingIndex, 1);\n this.#recordingsAvailable.splice(recordingIndex, 1);\n }\n\n getRecordingsAvailable(): string[] {\n return this.#recordingsAvailable;\n }\n\n resetProcessor(): void {\n this.#processor.reset();\n }\n}\n\n/**\n * This parsed trace file is used by the Model. It keeps multiple instances\n * of these so that the user can swap between them. The key is that it is\n * essentially the TraceFile plus whatever the model has parsed from it.\n */\nexport type ParsedTraceFile = Types.File.TraceFile&{\n parsedTrace: Handlers.Types.ParsedTrace | null,\n traceInsights: Insights.Types.TraceInsightSets | null,\n};\n\nexport const enum ModelUpdateType {\n COMPLETE = 'COMPLETE',\n PROGRESS_UPDATE = 'PROGRESS_UPDATE',\n}\n\nexport type ModelUpdateEventData = ModelUpdateEventComplete|ModelUpdateEventProgress;\n\nexport interface ModelUpdateEventComplete {\n type: ModelUpdateType.COMPLETE;\n data: 'done';\n}\nexport interface ModelUpdateEventProgress {\n type: ModelUpdateType.PROGRESS_UPDATE;\n data: TraceParseEventProgressData;\n}\n\nexport interface TraceParseEventProgressData {\n percent: number;\n}\n\nexport class ModelUpdateEvent extends Event {\n static readonly eventName = 'modelupdate';\n constructor(public data: ModelUpdateEventData) {\n super(ModelUpdateEvent.eventName);\n }\n}\n\ndeclare global {\n interface HTMLElementEventMap {\n [ModelUpdateEvent.eventName]: ModelUpdateEvent;\n }\n}\n\nexport function isModelUpdateDataComplete(eventData: ModelUpdateEventData): eventData is ModelUpdateEventComplete {\n return eventData.type === ModelUpdateType.COMPLETE;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ModelImpl.js","sourceRoot":"","sources":["../../../../../../front_end/models/trace/ModelImpl.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../core/platform/platform.js';\n\nimport * as Handlers from './handlers/handlers.js';\nimport * as Helpers from './helpers/helpers.js';\nimport type * as Insights from './insights/insights.js';\nimport {TraceParseProgressEvent, TraceProcessor} from './Processor.js';\nimport * as Types from './types/types.js';\n\n// Note: this model is implemented in a way that can support multiple trace\n// processors. Currently there is only one implemented, but you will see\n// references to \"processors\" plural because it can easily be extended in the future.\n\nexport interface ParseConfig {\n metadata?: Types.File.MetaData;\n isFreshRecording?: boolean;\n resolveSourceMap?: Types.Configuration.ParseOptions['resolveSourceMap'];\n}\n\n/**\n * The Model is responsible for parsing arrays of raw trace events and storing the\n * resulting data. It can store multiple traces at once, and can return the data for\n * any of them.\n *\n * Most uses of this class should be through `createWithAllHandlers`, but\n * `createWithSubsetOfHandlers` can be used to run just some handlers.\n **/\nexport class Model extends EventTarget {\n readonly #traces: ParsedTraceFile[] = [];\n readonly #syntheticEventsManagerByTrace: Helpers.SyntheticEvents.SyntheticEventsManager[] = [];\n readonly #nextNumberByDomain = new Map<string, number>();\n\n readonly #recordingsAvailable: string[] = [];\n #lastRecordingIndex = 0;\n #processor: TraceProcessor;\n #config: Types.Configuration.Configuration = Types.Configuration.defaults();\n\n static createWithAllHandlers(config?: Types.Configuration.Configuration): Model {\n return new Model(Handlers.ModelHandlers, config);\n }\n\n /**\n * Runs only the provided handlers.\n *\n * Callers must ensure they are providing all dependant handlers (although Meta is included automatically),\n * and must know that the result of `.parsedTrace` will be limited to the handlers provided, even though\n * the type won't reflect that.\n */\n static createWithSubsetOfHandlers(\n traceHandlers: Partial<Handlers.Types.Handlers>, config?: Types.Configuration.Configuration): Model {\n return new Model(traceHandlers as Handlers.Types.Handlers, config);\n }\n\n constructor(handlers: Handlers.Types.Handlers, config?: Types.Configuration.Configuration) {\n super();\n if (config) {\n this.#config = config;\n }\n this.#processor = new TraceProcessor(handlers, this.#config);\n }\n\n /**\n * Parses an array of trace events into a structured object containing all the\n * information parsed by the trace handlers.\n * You can `await` this function to pause execution until parsing is complete,\n * or instead rely on the `ModuleUpdateEvent` that is dispatched when the\n * parsing is finished.\n *\n * Once parsed, you then have to call the `parsedTrace` method, providing an\n * index of the trace you want to have the data for. This is because any model\n * can store a number of traces. Each trace is given an index, which starts at 0\n * and increments by one as a new trace is parsed.\n *\n * @example\n * // Awaiting the parse method() to block until parsing complete\n * await this.traceModel.parse(events);\n * const data = this.traceModel.parsedTrace(0)\n *\n * @example\n * // Using an event listener to be notified when tracing is complete.\n * this.traceModel.addEventListener(Trace.ModelUpdateEvent.eventName, (event) => {\n * if(event.data.data === 'done') {\n * // trace complete\n * const data = this.traceModel.parsedTrace(0);\n * }\n * });\n * void this.traceModel.parse(events);\n **/\n async parse(traceEvents: readonly Types.Events.Event[], config?: ParseConfig): Promise<void> {\n const metadata = config?.metadata || {};\n const isFreshRecording = config?.isFreshRecording || false;\n const isCPUProfile = metadata?.dataOrigin === Types.File.DataOrigin.CPU_PROFILE;\n // During parsing, periodically update any listeners on each processors'\n // progress (if they have any updates).\n const onTraceUpdate = (event: Event): void => {\n const {data} = event as TraceParseProgressEvent;\n this.dispatchEvent(new ModelUpdateEvent({type: ModelUpdateType.PROGRESS_UPDATE, data}));\n };\n\n this.#processor.addEventListener(TraceParseProgressEvent.eventName, onTraceUpdate);\n\n // Create a parsed trace file. It will be populated with data from the processor.\n const file: ParsedTraceFile = {\n traceEvents,\n metadata,\n parsedTrace: null,\n traceInsights: null,\n };\n\n try {\n // Wait for all outstanding promises before finishing the async execution,\n // but perform all tasks in parallel.\n const syntheticEventsManager = Helpers.SyntheticEvents.SyntheticEventsManager.createAndActivate(traceEvents);\n await this.#processor.parse(traceEvents, {\n isFreshRecording,\n isCPUProfile,\n metadata,\n resolveSourceMap: config?.resolveSourceMap,\n });\n this.#storeParsedFileData(file, this.#processor.parsedTrace, this.#processor.insights);\n // We only push the file onto this.#traces here once we know it's valid\n // and there's been no errors in the parsing.\n this.#traces.push(file);\n this.#syntheticEventsManagerByTrace.push(syntheticEventsManager);\n } catch (e) {\n throw e;\n } finally {\n // All processors have finished parsing, no more updates are expected.\n this.#processor.removeEventListener(TraceParseProgressEvent.eventName, onTraceUpdate);\n // Finally, update any listeners that all processors are 'done'.\n this.dispatchEvent(new ModelUpdateEvent({type: ModelUpdateType.COMPLETE, data: 'done'}));\n }\n }\n\n #storeParsedFileData(\n file: ParsedTraceFile, data: Handlers.Types.ParsedTrace|null,\n insights: Insights.Types.TraceInsightSets|null): void {\n file.parsedTrace = data;\n file.traceInsights = insights;\n this.#lastRecordingIndex++;\n let recordingName = `Trace ${this.#lastRecordingIndex}`;\n let origin: string|null = null;\n if (file.parsedTrace) {\n origin = Helpers.Trace.extractOriginFromTrace(file.parsedTrace.Meta.mainFrameURL);\n if (origin) {\n const nextSequenceForDomain = Platform.MapUtilities.getWithDefault(this.#nextNumberByDomain, origin, () => 1);\n recordingName = `${origin} (${nextSequenceForDomain})`;\n this.#nextNumberByDomain.set(origin, nextSequenceForDomain + 1);\n }\n }\n this.#recordingsAvailable.push(recordingName);\n }\n\n lastTraceIndex(): number {\n return this.size() - 1;\n }\n\n /**\n * Returns the parsed trace data indexed by the order in which it was stored.\n * If no index is given, the last stored parsed data is returned.\n */\n parsedTrace(index: number = this.#traces.length - 1): Handlers.Types.ParsedTrace|null {\n return this.#traces.at(index)?.parsedTrace ?? null;\n }\n\n traceInsights(index: number = this.#traces.length - 1): Insights.Types.TraceInsightSets|null {\n return this.#traces.at(index)?.traceInsights ?? null;\n }\n\n metadata(index: number = this.#traces.length - 1): Types.File.MetaData|null {\n return this.#traces.at(index)?.metadata ?? null;\n }\n\n overrideModifications(index: number, newModifications: Types.File.Modifications): void {\n if (this.#traces[index]) {\n this.#traces[index].metadata.modifications = newModifications;\n }\n }\n\n rawTraceEvents(index: number = this.#traces.length - 1): readonly Types.Events.Event[]|null {\n return this.#traces.at(index)?.traceEvents ?? null;\n }\n\n syntheticTraceEventsManager(index: number = this.#traces.length - 1): Helpers.SyntheticEvents.SyntheticEventsManager\n |null {\n return this.#syntheticEventsManagerByTrace.at(index) ?? null;\n }\n\n size(): number {\n return this.#traces.length;\n }\n\n deleteTraceByIndex(recordingIndex: number): void {\n this.#traces.splice(recordingIndex, 1);\n this.#recordingsAvailable.splice(recordingIndex, 1);\n }\n\n getRecordingsAvailable(): string[] {\n return this.#recordingsAvailable;\n }\n\n resetProcessor(): void {\n this.#processor.reset();\n }\n}\n\n/**\n * This parsed trace file is used by the Model. It keeps multiple instances\n * of these so that the user can swap between them. The key is that it is\n * essentially the TraceFile plus whatever the model has parsed from it.\n */\nexport type ParsedTraceFile = Types.File.TraceFile&{\n parsedTrace: Handlers.Types.ParsedTrace | null,\n traceInsights: Insights.Types.TraceInsightSets | null,\n};\n\nexport const enum ModelUpdateType {\n COMPLETE = 'COMPLETE',\n PROGRESS_UPDATE = 'PROGRESS_UPDATE',\n}\n\nexport type ModelUpdateEventData = ModelUpdateEventComplete|ModelUpdateEventProgress;\n\nexport interface ModelUpdateEventComplete {\n type: ModelUpdateType.COMPLETE;\n data: 'done';\n}\nexport interface ModelUpdateEventProgress {\n type: ModelUpdateType.PROGRESS_UPDATE;\n data: TraceParseEventProgressData;\n}\n\nexport interface TraceParseEventProgressData {\n percent: number;\n}\n\nexport class ModelUpdateEvent extends Event {\n static readonly eventName = 'modelupdate';\n constructor(public data: ModelUpdateEventData) {\n super(ModelUpdateEvent.eventName);\n }\n}\n\ndeclare global {\n interface HTMLElementEventMap {\n [ModelUpdateEvent.eventName]: ModelUpdateEvent;\n }\n}\n\nexport function isModelUpdateDataComplete(eventData: ModelUpdateEventData): eventData is ModelUpdateEventComplete {\n return eventData.type === ModelUpdateType.COMPLETE;\n}\n"]}
|
|
@@ -279,14 +279,15 @@ export class TraceProcessor extends EventTarget {
|
|
|
279
279
|
LCPDiscovery: null,
|
|
280
280
|
CLSCulprits: null,
|
|
281
281
|
RenderBlocking: null,
|
|
282
|
+
NetworkDependencyTree: null,
|
|
282
283
|
ImageDelivery: null,
|
|
283
284
|
DocumentLatency: null,
|
|
284
285
|
FontDisplay: null,
|
|
285
286
|
Viewport: null,
|
|
286
287
|
DOMSize: null,
|
|
287
288
|
ThirdParties: null,
|
|
289
|
+
DuplicateJavaScript: null,
|
|
288
290
|
SlowCSSSelector: null,
|
|
289
|
-
LongCriticalNetworkTree: null,
|
|
290
291
|
ForcedReflow: null,
|
|
291
292
|
};
|
|
292
293
|
// Determine the weights for each metric based on field data, utilizing the same scoring curve that Lighthouse uses.
|
|
@@ -349,27 +350,31 @@ export class TraceProcessor extends EventTarget {
|
|
|
349
350
|
insightSet.model = newModel;
|
|
350
351
|
}
|
|
351
352
|
#computeInsightSet(insights, parsedTrace, insightRunners, context, options) {
|
|
353
|
+
let id, urlString, navigation;
|
|
354
|
+
if (context.navigation) {
|
|
355
|
+
id = context.navigationId;
|
|
356
|
+
urlString = context.navigation.args.data?.documentLoaderURL ?? parsedTrace.Meta.mainFrameURL;
|
|
357
|
+
navigation = context.navigation;
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
id = Types.Events.NO_NAVIGATION;
|
|
361
|
+
urlString = parsedTrace.Meta.mainFrameURL;
|
|
362
|
+
}
|
|
352
363
|
const model = {};
|
|
353
364
|
for (const [name, insight] of Object.entries(insightRunners)) {
|
|
354
365
|
let insightResult;
|
|
355
366
|
try {
|
|
356
367
|
insightResult = insight.generateInsight(parsedTrace, context);
|
|
368
|
+
const navId = context.navigation?.args.data?.navigationId;
|
|
369
|
+
if (navId) {
|
|
370
|
+
insightResult.navigationId = navId;
|
|
371
|
+
}
|
|
357
372
|
}
|
|
358
373
|
catch (err) {
|
|
359
374
|
insightResult = err;
|
|
360
375
|
}
|
|
361
376
|
Object.assign(model, { [name]: insightResult });
|
|
362
377
|
}
|
|
363
|
-
let id, urlString, navigation;
|
|
364
|
-
if (context.navigation) {
|
|
365
|
-
id = context.navigationId;
|
|
366
|
-
urlString = context.navigation.args.data?.documentLoaderURL ?? parsedTrace.Meta.mainFrameURL;
|
|
367
|
-
navigation = context.navigation;
|
|
368
|
-
}
|
|
369
|
-
else {
|
|
370
|
-
id = Types.Events.NO_NAVIGATION;
|
|
371
|
-
urlString = parsedTrace.Meta.mainFrameURL;
|
|
372
|
-
}
|
|
373
378
|
let url;
|
|
374
379
|
try {
|
|
375
380
|
url = new URL(urlString);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Processor.js","sourceRoot":"","sources":["../../../../../../front_end/models/trace/Processor.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\nimport * as Handlers from './handlers/handlers.js';\nimport * as Helpers from './helpers/helpers.js';\nimport * as Insights from './insights/insights.js';\nimport * as Lantern from './lantern/lantern.js';\nimport * as LanternComputationData from './LanternComputationData.js';\nimport type * as Model from './ModelImpl.js';\nimport * as Types from './types/types.js';\n\nconst enum Status {\n IDLE = 'IDLE',\n PARSING = 'PARSING',\n FINISHED_PARSING = 'FINISHED_PARSING',\n ERRORED_WHILE_PARSING = 'ERRORED_WHILE_PARSING',\n}\n\nexport class TraceParseProgressEvent extends Event {\n static readonly eventName = 'traceparseprogress';\n constructor(public data: Model.TraceParseEventProgressData, init: EventInit = {bubbles: true}) {\n super(TraceParseProgressEvent.eventName, init);\n }\n}\n\n/**\n * Parsing a trace can take time. On large traces we see a breakdown of time like so:\n * - handleEvent() loop: ~20%\n * - finalize() loop: ~60%\n * - shallowClone calls: ~20%\n * The numbers below are set so we can report a progress percentage of [0...1]\n */\nconst enum ProgressPhase {\n HANDLE_EVENT = 0.2,\n FINALIZE = 0.8,\n CLONE = 1.0,\n}\nfunction calculateProgress(value: number, phase: ProgressPhase): number {\n // Finalize values should be [0.2...0.8]\n if (phase === ProgressPhase.FINALIZE) {\n return (value * (ProgressPhase.FINALIZE - ProgressPhase.HANDLE_EVENT)) + ProgressPhase.HANDLE_EVENT;\n }\n return value * phase;\n}\n\ndeclare global {\n interface HTMLElementEventMap {\n [TraceParseProgressEvent.eventName]: TraceParseProgressEvent;\n }\n}\n\nexport class TraceProcessor extends EventTarget {\n // We force the Meta handler to be enabled, so the TraceHandlers type here is\n // the model handlers the user passes in and the Meta handler.\n readonly #traceHandlers: Partial<Handlers.Types.Handlers>;\n #status = Status.IDLE;\n #modelConfiguration = Types.Configuration.defaults();\n #data: Handlers.Types.ParsedTrace|null = null;\n #insights: Insights.Types.TraceInsightSets|null = null;\n\n static createWithAllHandlers(): TraceProcessor {\n return new TraceProcessor(Handlers.ModelHandlers, Types.Configuration.defaults());\n }\n\n static getEnabledInsightRunners(parsedTrace: Handlers.Types.ParsedTrace): Partial<Insights.Types.InsightModelsType> {\n const enabledInsights = {} as Insights.Types.InsightModelsType;\n for (const [name, insight] of Object.entries(Insights.Models)) {\n const deps = insight.deps();\n if (deps.some(dep => !parsedTrace[dep])) {\n continue;\n }\n Object.assign(enabledInsights, {[name]: insight});\n }\n return enabledInsights;\n }\n\n constructor(traceHandlers: Partial<Handlers.Types.Handlers>, modelConfiguration?: Types.Configuration.Configuration) {\n super();\n\n this.#verifyHandlers(traceHandlers);\n this.#traceHandlers = {\n Meta: Handlers.ModelHandlers.Meta,\n ...traceHandlers,\n };\n if (modelConfiguration) {\n this.#modelConfiguration = modelConfiguration;\n }\n this.#passConfigToHandlers();\n }\n\n #passConfigToHandlers(): void {\n for (const handler of Object.values(this.#traceHandlers)) {\n // Bit of an odd double check, but without this TypeScript refuses to let\n // you call the function as it thinks it might be undefined.\n if ('handleUserConfig' in handler && handler.handleUserConfig) {\n handler.handleUserConfig(this.#modelConfiguration);\n }\n }\n }\n\n /**\n * When the user passes in a set of handlers, we want to ensure that we have all\n * the required handlers. Handlers can depend on other handlers, so if the user\n * passes in FooHandler which depends on BarHandler, they must also pass in\n * BarHandler too. This method verifies that all dependencies are met, and\n * throws if not.\n **/\n #verifyHandlers(providedHandlers: Partial<Handlers.Types.Handlers>): void {\n // Tiny optimisation: if the amount of provided handlers matches the amount\n // of handlers in the Handlers.ModelHandlers object, that means that the\n // user has passed in every handler we have. So therefore they cannot have\n // missed any, and there is no need to iterate through the handlers and\n // check the dependencies.\n if (Object.keys(providedHandlers).length === Object.keys(Handlers.ModelHandlers).length) {\n return;\n }\n const requiredHandlerKeys: Set<Handlers.Types.HandlerName> = new Set();\n for (const [handlerName, handler] of Object.entries(providedHandlers)) {\n requiredHandlerKeys.add(handlerName as Handlers.Types.HandlerName);\n const deps = 'deps' in handler ? handler.deps() : [];\n for (const depName of deps) {\n requiredHandlerKeys.add(depName);\n }\n }\n\n const providedHandlerKeys = new Set(Object.keys(providedHandlers));\n // We always force the Meta handler to be enabled when creating the\n // Processor, so if it is missing from the set the user gave us that is OK,\n // as we will have enabled it anyway.\n requiredHandlerKeys.delete('Meta');\n\n for (const requiredKey of requiredHandlerKeys) {\n if (!providedHandlerKeys.has(requiredKey)) {\n throw new Error(`Required handler ${requiredKey} not provided.`);\n }\n }\n }\n\n reset(): void {\n if (this.#status === Status.PARSING) {\n throw new Error('Trace processor can\\'t reset while parsing.');\n }\n\n const handlers = Object.values(this.#traceHandlers);\n for (const handler of handlers) {\n handler.reset();\n }\n\n this.#data = null;\n this.#insights = null;\n this.#status = Status.IDLE;\n }\n\n async parse(traceEvents: readonly Types.Events.Event[], options: Types.Configuration.ParseOptions): Promise<void> {\n if (this.#status !== Status.IDLE) {\n throw new Error(`Trace processor can't start parsing when not idle. Current state: ${this.#status}`);\n }\n try {\n this.#status = Status.PARSING;\n await this.#computeParsedTrace(traceEvents, options);\n if (this.#data && !options.isCPUProfile) { // We do not calculate insights for CPU Profiles.\n this.#computeInsights(this.#data, traceEvents, options);\n }\n this.#status = Status.FINISHED_PARSING;\n } catch (e) {\n this.#status = Status.ERRORED_WHILE_PARSING;\n throw e;\n }\n }\n\n /**\n * Run all the handlers and set the result to `#data`.\n */\n async #computeParsedTrace(traceEvents: readonly Types.Events.Event[], options: Types.Configuration.ParseOptions):\n Promise<void> {\n /**\n * We want to yield regularly to maintain responsiveness. If we yield too often, we're wasting idle time.\n * We could do this by checking `performance.now()` regularly, but it's an expensive call in such a hot loop.\n * `eventsPerChunk` is an approximated proxy metric.\n * But how big a chunk? We're aiming for long tasks that are no smaller than 100ms and not bigger than 200ms.\n * It's CPU dependent, so it should be calibrated on oldish hardware.\n * Illustration of a previous change to `eventsPerChunk`: https://imgur.com/wzp8BnR\n */\n const eventsPerChunk = 50_000;\n // Convert to array so that we are able to iterate all handlers multiple times.\n const sortedHandlers = [...sortHandlers(this.#traceHandlers).values()];\n\n // Reset.\n for (const handler of sortedHandlers) {\n handler.reset();\n }\n\n // Handle each event.\n for (let i = 0; i < traceEvents.length; ++i) {\n // Every so often we take a break just to render.\n if (i % eventsPerChunk === 0 && i) {\n // Take the opportunity to provide status update events.\n const percent = calculateProgress(i / traceEvents.length, ProgressPhase.HANDLE_EVENT);\n this.dispatchEvent(new TraceParseProgressEvent({percent}));\n // TODO(paulirish): consider using `scheduler.yield()` or `scheduler.postTask(() => {}, {priority: 'user-blocking'})`\n await new Promise(resolve => setTimeout(resolve, 0));\n }\n const event = traceEvents[i];\n for (let j = 0; j < sortedHandlers.length; ++j) {\n sortedHandlers[j].handleEvent(event);\n }\n }\n\n // Finalize.\n for (const [i, handler] of sortedHandlers.entries()) {\n if (handler.finalize) {\n // Yield to the UI because finalize() calls can be expensive\n // TODO(jacktfranklin): consider using `scheduler.yield()` or `scheduler.postTask(() => {}, {priority: 'user-blocking'})`\n await new Promise(resolve => setTimeout(resolve, 0));\n await handler.finalize(options);\n }\n const percent = calculateProgress(i / sortedHandlers.length, ProgressPhase.FINALIZE);\n this.dispatchEvent(new TraceParseProgressEvent({percent}));\n }\n\n // Handlers that depend on other handlers do so via .data(), which used to always\n // return a shallow clone of its internal data structures. However, that pattern\n // easily results in egregious amounts of allocation. Now .data() does not do any\n // cloning, and it happens here instead so that users of the trace processor may\n // still assume that the parsed data is theirs.\n // See: crbug/41484172\n const shallowClone = (value: unknown, recurse = true): unknown => {\n if (value instanceof Map) {\n return new Map(value);\n }\n if (value instanceof Set) {\n return new Set(value);\n }\n if (Array.isArray(value)) {\n return [...value];\n }\n if (typeof value === 'object' && value && recurse) {\n const obj: Record<string, unknown> = {};\n for (const [key, v] of Object.entries(value)) {\n obj[key] = shallowClone(v, false);\n }\n return obj;\n }\n return value;\n };\n\n const parsedTrace = {};\n for (const [name, handler] of Object.entries(this.#traceHandlers)) {\n const data = shallowClone(handler.data());\n Object.assign(parsedTrace, {[name]: data});\n }\n this.dispatchEvent(new TraceParseProgressEvent({percent: ProgressPhase.CLONE}));\n\n this.#data = parsedTrace as Handlers.Types.ParsedTrace;\n }\n\n get parsedTrace(): Handlers.Types.ParsedTrace|null {\n if (this.#status !== Status.FINISHED_PARSING) {\n return null;\n }\n\n return this.#data;\n }\n\n get insights(): Insights.Types.TraceInsightSets|null {\n if (this.#status !== Status.FINISHED_PARSING) {\n return null;\n }\n\n return this.#insights;\n }\n\n #createLanternContext(\n parsedTrace: Handlers.Types.ParsedTrace, traceEvents: readonly Types.Events.Event[], frameId: string,\n navigationId: string): Insights.Types.LanternContext|undefined {\n // Check for required handlers.\n if (!parsedTrace.NetworkRequests || !parsedTrace.Workers || !parsedTrace.PageLoadMetrics) {\n return;\n }\n if (!parsedTrace.NetworkRequests.byTime.length) {\n throw new Lantern.Core.LanternError('No network requests found in trace');\n }\n\n const navStarts = parsedTrace.Meta.navigationsByFrameId.get(frameId);\n const navStartIndex = navStarts?.findIndex(n => n.args.data?.navigationId === navigationId);\n if (!navStarts || navStartIndex === undefined || navStartIndex === -1) {\n throw new Lantern.Core.LanternError('Could not find navigation start');\n }\n\n const startTime = navStarts[navStartIndex].ts;\n const endTime = navStartIndex + 1 < navStarts.length ? navStarts[navStartIndex + 1].ts : Number.POSITIVE_INFINITY;\n const boundedTraceEvents = traceEvents.filter(e => e.ts >= startTime && e.ts < endTime);\n\n // Lantern.Types.TraceEvent and Types.Events.Event represent the same\n // object - a trace event - but one is more flexible than the other. It should be safe to cast between them.\n const trace: Lantern.Types.Trace = {\n traceEvents: boundedTraceEvents as unknown as Lantern.Types.TraceEvent[],\n };\n\n const requests = LanternComputationData.createNetworkRequests(trace, parsedTrace, startTime, endTime);\n const graph = LanternComputationData.createGraph(requests, trace, parsedTrace);\n const processedNavigation = LanternComputationData.createProcessedNavigation(parsedTrace, frameId, navigationId);\n\n const networkAnalysis = Lantern.Core.NetworkAnalyzer.analyze(requests);\n if (!networkAnalysis) {\n return;\n }\n\n const simulator: Lantern.Simulation.Simulator<Types.Events.SyntheticNetworkRequest> =\n Lantern.Simulation.Simulator.createSimulator({\n // TODO(crbug.com/372674229): if devtools throttling was on, does this network analysis capture\n // that? Do we need to set 'devtools' throttlingMethod?\n networkAnalysis,\n throttlingMethod: 'provided',\n });\n\n const computeData = {graph, simulator, processedNavigation};\n const fcpResult = Lantern.Metrics.FirstContentfulPaint.compute(computeData);\n const lcpResult = Lantern.Metrics.LargestContentfulPaint.compute(computeData, {fcpResult});\n const interactiveResult = Lantern.Metrics.Interactive.compute(computeData, {lcpResult});\n const tbtResult = Lantern.Metrics.TotalBlockingTime.compute(computeData, {fcpResult, interactiveResult});\n const metrics = {\n firstContentfulPaint: fcpResult,\n interactive: interactiveResult,\n largestContentfulPaint: lcpResult,\n totalBlockingTime: tbtResult,\n };\n\n return {graph, simulator, metrics};\n }\n\n /**\n * Sort the insight models based on the impact of each insight's estimated savings, additionally weighted by the\n * worst metrics according to field data (if present).\n */\n sortInsightSet(\n insights: Insights.Types.TraceInsightSets, insightSet: Insights.Types.InsightSet,\n metadata: Types.File.MetaData|null): void {\n // The initial order of the insights is alphabetical, based on `front_end/models/trace/insights/Models.ts`.\n // The order here provides a baseline that groups insights in a more logical way.\n const baselineOrder: Record<keyof Insights.Types.InsightModels, null> = {\n InteractionToNextPaint: null,\n LCPPhases: null,\n LCPDiscovery: null,\n CLSCulprits: null,\n RenderBlocking: null,\n ImageDelivery: null,\n DocumentLatency: null,\n FontDisplay: null,\n Viewport: null,\n DOMSize: null,\n ThirdParties: null,\n SlowCSSSelector: null,\n LongCriticalNetworkTree: null,\n ForcedReflow: null,\n };\n\n // Determine the weights for each metric based on field data, utilizing the same scoring curve that Lighthouse uses.\n const weights = Insights.Common.calculateMetricWeightsForSorting(insightSet, metadata);\n\n // Normalize the estimated savings to a single number, weighted by its relative impact\n // to the page experience based on the same scoring curve that Lighthouse uses.\n const observedLcp = Insights.Common.getLCP(insights, insightSet.id)?.value;\n const observedCls = Insights.Common.getCLS(insights, insightSet.id).value;\n\n // INP is special - if users did not interact with the page, we'll have no INP, but we should still\n // be able to prioritize insights based on this metric. When we observe no interaction, instead use\n // a default value for the baseline INP.\n const observedInp = Insights.Common.getINP(insights, insightSet.id)?.value ?? 200;\n\n const observedLcpScore =\n observedLcp !== undefined ? Insights.Common.evaluateLCPMetricScore(observedLcp) : undefined;\n const observedInpScore = Insights.Common.evaluateINPMetricScore(observedInp);\n const observedClsScore = Insights.Common.evaluateCLSMetricScore(observedCls);\n\n const insightToSortingRank = new Map<string, number>();\n for (const [name, model] of Object.entries(insightSet.model)) {\n const lcp = model.metricSavings?.LCP ?? 0;\n const inp = model.metricSavings?.INP ?? 0;\n const cls = model.metricSavings?.CLS ?? 0;\n\n const lcpPostSavings = observedLcp !== undefined ? Math.max(0, observedLcp - lcp) : undefined;\n const inpPostSavings = Math.max(0, observedInp - inp);\n const clsPostSavings = Math.max(0, observedCls - cls);\n\n let score = 0;\n if (weights.lcp && lcp && observedLcpScore !== undefined && lcpPostSavings !== undefined) {\n score += weights.lcp * (Insights.Common.evaluateLCPMetricScore(lcpPostSavings) - observedLcpScore);\n }\n if (weights.inp && inp && observedInpScore !== undefined) {\n score += weights.inp * (Insights.Common.evaluateINPMetricScore(inpPostSavings) - observedInpScore);\n }\n if (weights.cls && cls && observedClsScore !== undefined) {\n score += weights.cls * (Insights.Common.evaluateCLSMetricScore(clsPostSavings) - observedClsScore);\n }\n\n insightToSortingRank.set(name, score);\n }\n\n // Now perform the actual sorting.\n const baselineOrderKeys = Object.keys(baselineOrder);\n const orderedKeys = Object.keys(insightSet.model);\n orderedKeys.sort((a, b) => {\n const a1 = baselineOrderKeys.indexOf(a);\n const b1 = baselineOrderKeys.indexOf(b);\n if (a1 >= 0 && b1 >= 0) {\n return a1 - b1;\n }\n if (a1 >= 0) {\n return -1;\n }\n if (b1 >= 0) {\n return 1;\n }\n return 0;\n });\n orderedKeys.sort((a, b) => (insightToSortingRank.get(b) ?? 0) - (insightToSortingRank.get(a) ?? 0));\n\n const newModel = {} as Insights.Types.InsightModels;\n for (const key of orderedKeys as Array<keyof Insights.Types.InsightModels>) {\n const model = insightSet.model[key];\n // @ts-expect-error Maybe someday typescript will be powerful enough to handle this.\n newModel[key] = model;\n }\n insightSet.model = newModel;\n }\n\n #computeInsightSet(\n insights: Insights.Types.TraceInsightSets, parsedTrace: Handlers.Types.ParsedTrace,\n insightRunners: Partial<typeof Insights.Models>, context: Insights.Types.InsightSetContext,\n options: Types.Configuration.ParseOptions): void {\n const model = {} as Insights.Types.InsightSet['model'];\n\n for (const [name, insight] of Object.entries(insightRunners)) {\n let insightResult;\n try {\n insightResult = insight.generateInsight(parsedTrace, context);\n } catch (err) {\n insightResult = err;\n }\n Object.assign(model, {[name]: insightResult});\n }\n\n let id, urlString, navigation;\n if (context.navigation) {\n id = context.navigationId;\n urlString = context.navigation.args.data?.documentLoaderURL ?? parsedTrace.Meta.mainFrameURL;\n navigation = context.navigation;\n } else {\n id = Types.Events.NO_NAVIGATION;\n urlString = parsedTrace.Meta.mainFrameURL;\n }\n\n let url;\n try {\n url = new URL(urlString);\n } catch {\n // We're pretty sure this only happens for our test fixture: missing-url.json.gz. Shouldn't\n // happen for real traces.\n return;\n }\n\n const insightSet: Insights.Types.InsightSet = {\n id,\n url,\n navigation,\n frameId: context.frameId,\n bounds: context.bounds,\n model,\n };\n insights.set(insightSet.id, insightSet);\n this.sortInsightSet(insights, insightSet, options.metadata ?? null);\n }\n\n /**\n * Run all the insights and set the result to `#insights`.\n */\n #computeInsights(\n parsedTrace: Handlers.Types.ParsedTrace, traceEvents: readonly Types.Events.Event[],\n options: Types.Configuration.ParseOptions): void {\n this.#insights = new Map();\n\n const enabledInsightRunners = TraceProcessor.getEnabledInsightRunners(parsedTrace);\n\n const navigations = parsedTrace.Meta.mainFrameNavigations.filter(\n navigation => navigation.args.frame && navigation.args.data?.navigationId);\n\n // Check if there is a meaningful chunk of work happening prior to the first navigation.\n // If so, we run the insights on that initial bounds.\n // Otherwise, there are no navigations and we do a no-navigation insights pass on the entire trace.\n if (navigations.length) {\n const bounds = Helpers.Timing.traceWindowFromMicroSeconds(parsedTrace.Meta.traceBounds.min, navigations[0].ts);\n // When using \"Record and reload\" option, it typically takes ~5ms. So use 50ms to be safe.\n const threshold = Helpers.Timing.milliToMicro(50 as Types.Timing.Milli);\n if (bounds.range > threshold) {\n const context: Insights.Types.InsightSetContext = {\n bounds,\n frameId: parsedTrace.Meta.mainFrameId,\n };\n this.#computeInsightSet(this.#insights, parsedTrace, enabledInsightRunners, context, options);\n }\n // If threshold is not met, then the very beginning of the trace is ignored by the insights engine.\n } else {\n const context: Insights.Types.InsightSetContext = {\n bounds: parsedTrace.Meta.traceBounds,\n frameId: parsedTrace.Meta.mainFrameId,\n };\n this.#computeInsightSet(this.#insights, parsedTrace, enabledInsightRunners, context, options);\n }\n\n // Now run the insights for each navigation in isolation.\n for (const [i, navigation] of navigations.entries()) {\n // The above filter guarantees these are present.\n const frameId = navigation.args.frame;\n const navigationId = navigation.args.data?.navigationId as string;\n\n // The lantern sub-context is optional on InsightSetContext, so not setting it is OK.\n // This is also a hedge against an error inside Lantern resulting in breaking the entire performance panel.\n // Additionally, many trace fixtures are too old to be processed by Lantern.\n let lantern;\n try {\n lantern = this.#createLanternContext(parsedTrace, traceEvents, frameId, navigationId);\n } catch (e) {\n // Don't allow an error in constructing the Lantern graphs to break the rest of the trace processor.\n // Log unexpected errors, but suppress anything that occurs from a trace being too old.\n // Otherwise tests using old fixtures become way too noisy.\n const expectedErrors = [\n 'mainDocumentRequest not found',\n 'missing metric scores for main frame',\n 'missing metric: FCP',\n 'missing metric: LCP',\n 'No network requests found in trace',\n 'Trace is too old',\n ];\n if (!(e instanceof Lantern.Core.LanternError)) {\n // If this wasn't a managed LanternError, the stack trace is likely needed for debugging.\n console.error(e);\n } else if (!expectedErrors.some(err => e.message === err)) {\n // To reduce noise from tests, only print errors that are not expected to occur because a trace is\n // too old (for which there is no single check).\n console.error(e);\n }\n }\n\n const min = navigation.ts;\n const max = i + 1 < navigations.length ? navigations[i + 1].ts : parsedTrace.Meta.traceBounds.max;\n const bounds = Helpers.Timing.traceWindowFromMicroSeconds(min, max);\n const context: Insights.Types.InsightSetContext = {\n bounds,\n frameId,\n navigation,\n navigationId,\n lantern,\n };\n\n this.#computeInsightSet(this.#insights, parsedTrace, enabledInsightRunners, context, options);\n }\n }\n}\n\n/**\n * Some Handlers need data provided by others. Dependencies of a handler handler are\n * declared in the `deps` field.\n * @returns A map from trace event handler name to trace event handler whose entries\n * iterate in such a way that each handler is visited after its dependencies.\n */\nexport function sortHandlers(traceHandlers: Partial<{[key in Handlers.Types.HandlerName]: Handlers.Types.Handler}>):\n Map<Handlers.Types.HandlerName, Handlers.Types.Handler> {\n const sortedMap = new Map<Handlers.Types.HandlerName, Handlers.Types.Handler>();\n const visited = new Set<Handlers.Types.HandlerName>();\n const visitHandler = (handlerName: Handlers.Types.HandlerName): void => {\n if (sortedMap.has(handlerName)) {\n return;\n }\n if (visited.has(handlerName)) {\n let stackPath = '';\n for (const handler of visited) {\n if (stackPath || handler === handlerName) {\n stackPath += `${handler}->`;\n }\n }\n stackPath += handlerName;\n throw new Error(`Found dependency cycle in trace event handlers: ${stackPath}`);\n }\n visited.add(handlerName);\n const handler = traceHandlers[handlerName];\n if (!handler) {\n return;\n }\n const deps = handler.deps?.();\n if (deps) {\n deps.forEach(visitHandler);\n }\n sortedMap.set(handlerName, handler);\n };\n\n for (const handlerName of Object.keys(traceHandlers)) {\n visitHandler(handlerName as Handlers.Types.HandlerName);\n }\n return sortedMap;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Processor.js","sourceRoot":"","sources":["../../../../../../front_end/models/trace/Processor.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Handlers from './handlers/handlers.js';\nimport * as Helpers from './helpers/helpers.js';\nimport * as Insights from './insights/insights.js';\nimport * as Lantern from './lantern/lantern.js';\nimport * as LanternComputationData from './LanternComputationData.js';\nimport type * as Model from './ModelImpl.js';\nimport * as Types from './types/types.js';\n\nconst enum Status {\n IDLE = 'IDLE',\n PARSING = 'PARSING',\n FINISHED_PARSING = 'FINISHED_PARSING',\n ERRORED_WHILE_PARSING = 'ERRORED_WHILE_PARSING',\n}\n\nexport class TraceParseProgressEvent extends Event {\n static readonly eventName = 'traceparseprogress';\n constructor(public data: Model.TraceParseEventProgressData, init: EventInit = {bubbles: true}) {\n super(TraceParseProgressEvent.eventName, init);\n }\n}\n\n/**\n * Parsing a trace can take time. On large traces we see a breakdown of time like so:\n * - handleEvent() loop: ~20%\n * - finalize() loop: ~60%\n * - shallowClone calls: ~20%\n * The numbers below are set so we can report a progress percentage of [0...1]\n */\nconst enum ProgressPhase {\n HANDLE_EVENT = 0.2,\n FINALIZE = 0.8,\n CLONE = 1.0,\n}\nfunction calculateProgress(value: number, phase: ProgressPhase): number {\n // Finalize values should be [0.2...0.8]\n if (phase === ProgressPhase.FINALIZE) {\n return (value * (ProgressPhase.FINALIZE - ProgressPhase.HANDLE_EVENT)) + ProgressPhase.HANDLE_EVENT;\n }\n return value * phase;\n}\n\ndeclare global {\n interface HTMLElementEventMap {\n [TraceParseProgressEvent.eventName]: TraceParseProgressEvent;\n }\n}\n\nexport class TraceProcessor extends EventTarget {\n // We force the Meta handler to be enabled, so the TraceHandlers type here is\n // the model handlers the user passes in and the Meta handler.\n readonly #traceHandlers: Partial<Handlers.Types.Handlers>;\n #status = Status.IDLE;\n #modelConfiguration = Types.Configuration.defaults();\n #data: Handlers.Types.ParsedTrace|null = null;\n #insights: Insights.Types.TraceInsightSets|null = null;\n\n static createWithAllHandlers(): TraceProcessor {\n return new TraceProcessor(Handlers.ModelHandlers, Types.Configuration.defaults());\n }\n\n static getEnabledInsightRunners(parsedTrace: Handlers.Types.ParsedTrace): Partial<Insights.Types.InsightModelsType> {\n const enabledInsights = {} as Insights.Types.InsightModelsType;\n for (const [name, insight] of Object.entries(Insights.Models)) {\n const deps = insight.deps();\n if (deps.some(dep => !parsedTrace[dep])) {\n continue;\n }\n Object.assign(enabledInsights, {[name]: insight});\n }\n return enabledInsights;\n }\n\n constructor(traceHandlers: Partial<Handlers.Types.Handlers>, modelConfiguration?: Types.Configuration.Configuration) {\n super();\n\n this.#verifyHandlers(traceHandlers);\n this.#traceHandlers = {\n Meta: Handlers.ModelHandlers.Meta,\n ...traceHandlers,\n };\n if (modelConfiguration) {\n this.#modelConfiguration = modelConfiguration;\n }\n this.#passConfigToHandlers();\n }\n\n #passConfigToHandlers(): void {\n for (const handler of Object.values(this.#traceHandlers)) {\n // Bit of an odd double check, but without this TypeScript refuses to let\n // you call the function as it thinks it might be undefined.\n if ('handleUserConfig' in handler && handler.handleUserConfig) {\n handler.handleUserConfig(this.#modelConfiguration);\n }\n }\n }\n\n /**\n * When the user passes in a set of handlers, we want to ensure that we have all\n * the required handlers. Handlers can depend on other handlers, so if the user\n * passes in FooHandler which depends on BarHandler, they must also pass in\n * BarHandler too. This method verifies that all dependencies are met, and\n * throws if not.\n **/\n #verifyHandlers(providedHandlers: Partial<Handlers.Types.Handlers>): void {\n // Tiny optimisation: if the amount of provided handlers matches the amount\n // of handlers in the Handlers.ModelHandlers object, that means that the\n // user has passed in every handler we have. So therefore they cannot have\n // missed any, and there is no need to iterate through the handlers and\n // check the dependencies.\n if (Object.keys(providedHandlers).length === Object.keys(Handlers.ModelHandlers).length) {\n return;\n }\n const requiredHandlerKeys = new Set<Handlers.Types.HandlerName>();\n for (const [handlerName, handler] of Object.entries(providedHandlers)) {\n requiredHandlerKeys.add(handlerName as Handlers.Types.HandlerName);\n const deps = 'deps' in handler ? handler.deps() : [];\n for (const depName of deps) {\n requiredHandlerKeys.add(depName);\n }\n }\n\n const providedHandlerKeys = new Set(Object.keys(providedHandlers));\n // We always force the Meta handler to be enabled when creating the\n // Processor, so if it is missing from the set the user gave us that is OK,\n // as we will have enabled it anyway.\n requiredHandlerKeys.delete('Meta');\n\n for (const requiredKey of requiredHandlerKeys) {\n if (!providedHandlerKeys.has(requiredKey)) {\n throw new Error(`Required handler ${requiredKey} not provided.`);\n }\n }\n }\n\n reset(): void {\n if (this.#status === Status.PARSING) {\n throw new Error('Trace processor can\\'t reset while parsing.');\n }\n\n const handlers = Object.values(this.#traceHandlers);\n for (const handler of handlers) {\n handler.reset();\n }\n\n this.#data = null;\n this.#insights = null;\n this.#status = Status.IDLE;\n }\n\n async parse(traceEvents: readonly Types.Events.Event[], options: Types.Configuration.ParseOptions): Promise<void> {\n if (this.#status !== Status.IDLE) {\n throw new Error(`Trace processor can't start parsing when not idle. Current state: ${this.#status}`);\n }\n try {\n this.#status = Status.PARSING;\n await this.#computeParsedTrace(traceEvents, options);\n if (this.#data && !options.isCPUProfile) { // We do not calculate insights for CPU Profiles.\n this.#computeInsights(this.#data, traceEvents, options);\n }\n this.#status = Status.FINISHED_PARSING;\n } catch (e) {\n this.#status = Status.ERRORED_WHILE_PARSING;\n throw e;\n }\n }\n\n /**\n * Run all the handlers and set the result to `#data`.\n */\n async #computeParsedTrace(traceEvents: readonly Types.Events.Event[], options: Types.Configuration.ParseOptions):\n Promise<void> {\n /**\n * We want to yield regularly to maintain responsiveness. If we yield too often, we're wasting idle time.\n * We could do this by checking `performance.now()` regularly, but it's an expensive call in such a hot loop.\n * `eventsPerChunk` is an approximated proxy metric.\n * But how big a chunk? We're aiming for long tasks that are no smaller than 100ms and not bigger than 200ms.\n * It's CPU dependent, so it should be calibrated on oldish hardware.\n * Illustration of a previous change to `eventsPerChunk`: https://imgur.com/wzp8BnR\n */\n const eventsPerChunk = 50_000;\n // Convert to array so that we are able to iterate all handlers multiple times.\n const sortedHandlers = [...sortHandlers(this.#traceHandlers).values()];\n\n // Reset.\n for (const handler of sortedHandlers) {\n handler.reset();\n }\n\n // Handle each event.\n for (let i = 0; i < traceEvents.length; ++i) {\n // Every so often we take a break just to render.\n if (i % eventsPerChunk === 0 && i) {\n // Take the opportunity to provide status update events.\n const percent = calculateProgress(i / traceEvents.length, ProgressPhase.HANDLE_EVENT);\n this.dispatchEvent(new TraceParseProgressEvent({percent}));\n // TODO(paulirish): consider using `scheduler.yield()` or `scheduler.postTask(() => {}, {priority: 'user-blocking'})`\n await new Promise(resolve => setTimeout(resolve, 0));\n }\n const event = traceEvents[i];\n for (let j = 0; j < sortedHandlers.length; ++j) {\n sortedHandlers[j].handleEvent(event);\n }\n }\n\n // Finalize.\n for (const [i, handler] of sortedHandlers.entries()) {\n if (handler.finalize) {\n // Yield to the UI because finalize() calls can be expensive\n // TODO(jacktfranklin): consider using `scheduler.yield()` or `scheduler.postTask(() => {}, {priority: 'user-blocking'})`\n await new Promise(resolve => setTimeout(resolve, 0));\n await handler.finalize(options);\n }\n const percent = calculateProgress(i / sortedHandlers.length, ProgressPhase.FINALIZE);\n this.dispatchEvent(new TraceParseProgressEvent({percent}));\n }\n\n // Handlers that depend on other handlers do so via .data(), which used to always\n // return a shallow clone of its internal data structures. However, that pattern\n // easily results in egregious amounts of allocation. Now .data() does not do any\n // cloning, and it happens here instead so that users of the trace processor may\n // still assume that the parsed data is theirs.\n // See: crbug/41484172\n const shallowClone = (value: unknown, recurse = true): unknown => {\n if (value instanceof Map) {\n return new Map(value);\n }\n if (value instanceof Set) {\n return new Set(value);\n }\n if (Array.isArray(value)) {\n return [...value];\n }\n if (typeof value === 'object' && value && recurse) {\n const obj: Record<string, unknown> = {};\n for (const [key, v] of Object.entries(value)) {\n obj[key] = shallowClone(v, false);\n }\n return obj;\n }\n return value;\n };\n\n const parsedTrace = {};\n for (const [name, handler] of Object.entries(this.#traceHandlers)) {\n const data = shallowClone(handler.data());\n Object.assign(parsedTrace, {[name]: data});\n }\n this.dispatchEvent(new TraceParseProgressEvent({percent: ProgressPhase.CLONE}));\n\n this.#data = parsedTrace as Handlers.Types.ParsedTrace;\n }\n\n get parsedTrace(): Handlers.Types.ParsedTrace|null {\n if (this.#status !== Status.FINISHED_PARSING) {\n return null;\n }\n\n return this.#data;\n }\n\n get insights(): Insights.Types.TraceInsightSets|null {\n if (this.#status !== Status.FINISHED_PARSING) {\n return null;\n }\n\n return this.#insights;\n }\n\n #createLanternContext(\n parsedTrace: Handlers.Types.ParsedTrace, traceEvents: readonly Types.Events.Event[], frameId: string,\n navigationId: string): Insights.Types.LanternContext|undefined {\n // Check for required handlers.\n if (!parsedTrace.NetworkRequests || !parsedTrace.Workers || !parsedTrace.PageLoadMetrics) {\n return;\n }\n if (!parsedTrace.NetworkRequests.byTime.length) {\n throw new Lantern.Core.LanternError('No network requests found in trace');\n }\n\n const navStarts = parsedTrace.Meta.navigationsByFrameId.get(frameId);\n const navStartIndex = navStarts?.findIndex(n => n.args.data?.navigationId === navigationId);\n if (!navStarts || navStartIndex === undefined || navStartIndex === -1) {\n throw new Lantern.Core.LanternError('Could not find navigation start');\n }\n\n const startTime = navStarts[navStartIndex].ts;\n const endTime = navStartIndex + 1 < navStarts.length ? navStarts[navStartIndex + 1].ts : Number.POSITIVE_INFINITY;\n const boundedTraceEvents = traceEvents.filter(e => e.ts >= startTime && e.ts < endTime);\n\n // Lantern.Types.TraceEvent and Types.Events.Event represent the same\n // object - a trace event - but one is more flexible than the other. It should be safe to cast between them.\n const trace: Lantern.Types.Trace = {\n traceEvents: boundedTraceEvents as unknown as Lantern.Types.TraceEvent[],\n };\n\n const requests = LanternComputationData.createNetworkRequests(trace, parsedTrace, startTime, endTime);\n const graph = LanternComputationData.createGraph(requests, trace, parsedTrace);\n const processedNavigation = LanternComputationData.createProcessedNavigation(parsedTrace, frameId, navigationId);\n\n const networkAnalysis = Lantern.Core.NetworkAnalyzer.analyze(requests);\n if (!networkAnalysis) {\n return;\n }\n\n const simulator: Lantern.Simulation.Simulator<Types.Events.SyntheticNetworkRequest> =\n Lantern.Simulation.Simulator.createSimulator({\n // TODO(crbug.com/372674229): if devtools throttling was on, does this network analysis capture\n // that? Do we need to set 'devtools' throttlingMethod?\n networkAnalysis,\n throttlingMethod: 'provided',\n });\n\n const computeData = {graph, simulator, processedNavigation};\n const fcpResult = Lantern.Metrics.FirstContentfulPaint.compute(computeData);\n const lcpResult = Lantern.Metrics.LargestContentfulPaint.compute(computeData, {fcpResult});\n const interactiveResult = Lantern.Metrics.Interactive.compute(computeData, {lcpResult});\n const tbtResult = Lantern.Metrics.TotalBlockingTime.compute(computeData, {fcpResult, interactiveResult});\n const metrics = {\n firstContentfulPaint: fcpResult,\n interactive: interactiveResult,\n largestContentfulPaint: lcpResult,\n totalBlockingTime: tbtResult,\n };\n\n return {graph, simulator, metrics};\n }\n\n /**\n * Sort the insight models based on the impact of each insight's estimated savings, additionally weighted by the\n * worst metrics according to field data (if present).\n */\n sortInsightSet(\n insights: Insights.Types.TraceInsightSets, insightSet: Insights.Types.InsightSet,\n metadata: Types.File.MetaData|null): void {\n // The initial order of the insights is alphabetical, based on `front_end/models/trace/insights/Models.ts`.\n // The order here provides a baseline that groups insights in a more logical way.\n const baselineOrder: Record<keyof Insights.Types.InsightModels, null> = {\n InteractionToNextPaint: null,\n LCPPhases: null,\n LCPDiscovery: null,\n CLSCulprits: null,\n RenderBlocking: null,\n NetworkDependencyTree: null,\n ImageDelivery: null,\n DocumentLatency: null,\n FontDisplay: null,\n Viewport: null,\n DOMSize: null,\n ThirdParties: null,\n DuplicateJavaScript: null,\n SlowCSSSelector: null,\n ForcedReflow: null,\n };\n\n // Determine the weights for each metric based on field data, utilizing the same scoring curve that Lighthouse uses.\n const weights = Insights.Common.calculateMetricWeightsForSorting(insightSet, metadata);\n\n // Normalize the estimated savings to a single number, weighted by its relative impact\n // to the page experience based on the same scoring curve that Lighthouse uses.\n const observedLcp = Insights.Common.getLCP(insights, insightSet.id)?.value;\n const observedCls = Insights.Common.getCLS(insights, insightSet.id).value;\n\n // INP is special - if users did not interact with the page, we'll have no INP, but we should still\n // be able to prioritize insights based on this metric. When we observe no interaction, instead use\n // a default value for the baseline INP.\n const observedInp = Insights.Common.getINP(insights, insightSet.id)?.value ?? 200;\n\n const observedLcpScore =\n observedLcp !== undefined ? Insights.Common.evaluateLCPMetricScore(observedLcp) : undefined;\n const observedInpScore = Insights.Common.evaluateINPMetricScore(observedInp);\n const observedClsScore = Insights.Common.evaluateCLSMetricScore(observedCls);\n\n const insightToSortingRank = new Map<string, number>();\n for (const [name, model] of Object.entries(insightSet.model)) {\n const lcp = model.metricSavings?.LCP ?? 0;\n const inp = model.metricSavings?.INP ?? 0;\n const cls = model.metricSavings?.CLS ?? 0;\n\n const lcpPostSavings = observedLcp !== undefined ? Math.max(0, observedLcp - lcp) : undefined;\n const inpPostSavings = Math.max(0, observedInp - inp);\n const clsPostSavings = Math.max(0, observedCls - cls);\n\n let score = 0;\n if (weights.lcp && lcp && observedLcpScore !== undefined && lcpPostSavings !== undefined) {\n score += weights.lcp * (Insights.Common.evaluateLCPMetricScore(lcpPostSavings) - observedLcpScore);\n }\n if (weights.inp && inp && observedInpScore !== undefined) {\n score += weights.inp * (Insights.Common.evaluateINPMetricScore(inpPostSavings) - observedInpScore);\n }\n if (weights.cls && cls && observedClsScore !== undefined) {\n score += weights.cls * (Insights.Common.evaluateCLSMetricScore(clsPostSavings) - observedClsScore);\n }\n\n insightToSortingRank.set(name, score);\n }\n\n // Now perform the actual sorting.\n const baselineOrderKeys = Object.keys(baselineOrder);\n const orderedKeys = Object.keys(insightSet.model);\n orderedKeys.sort((a, b) => {\n const a1 = baselineOrderKeys.indexOf(a);\n const b1 = baselineOrderKeys.indexOf(b);\n if (a1 >= 0 && b1 >= 0) {\n return a1 - b1;\n }\n if (a1 >= 0) {\n return -1;\n }\n if (b1 >= 0) {\n return 1;\n }\n return 0;\n });\n orderedKeys.sort((a, b) => (insightToSortingRank.get(b) ?? 0) - (insightToSortingRank.get(a) ?? 0));\n\n const newModel = {} as Insights.Types.InsightModels;\n for (const key of orderedKeys as Array<keyof Insights.Types.InsightModels>) {\n const model = insightSet.model[key];\n // @ts-expect-error Maybe someday typescript will be powerful enough to handle this.\n newModel[key] = model;\n }\n insightSet.model = newModel;\n }\n\n #computeInsightSet(\n insights: Insights.Types.TraceInsightSets, parsedTrace: Handlers.Types.ParsedTrace,\n insightRunners: Partial<typeof Insights.Models>, context: Insights.Types.InsightSetContext,\n options: Types.Configuration.ParseOptions): void {\n let id, urlString, navigation;\n if (context.navigation) {\n id = context.navigationId;\n urlString = context.navigation.args.data?.documentLoaderURL ?? parsedTrace.Meta.mainFrameURL;\n navigation = context.navigation;\n } else {\n id = Types.Events.NO_NAVIGATION;\n urlString = parsedTrace.Meta.mainFrameURL;\n }\n\n const model = {} as Insights.Types.InsightSet['model'];\n\n for (const [name, insight] of Object.entries(insightRunners)) {\n let insightResult;\n try {\n insightResult = insight.generateInsight(parsedTrace, context);\n const navId = context.navigation?.args.data?.navigationId;\n if (navId) {\n insightResult.navigationId = navId;\n }\n } catch (err) {\n insightResult = err;\n }\n Object.assign(model, {[name]: insightResult});\n }\n\n let url;\n try {\n url = new URL(urlString);\n } catch {\n // We're pretty sure this only happens for our test fixture: missing-url.json.gz. Shouldn't\n // happen for real traces.\n return;\n }\n\n const insightSet: Insights.Types.InsightSet = {\n id,\n url,\n navigation,\n frameId: context.frameId,\n bounds: context.bounds,\n model,\n };\n insights.set(insightSet.id, insightSet);\n this.sortInsightSet(insights, insightSet, options.metadata ?? null);\n }\n\n /**\n * Run all the insights and set the result to `#insights`.\n */\n #computeInsights(\n parsedTrace: Handlers.Types.ParsedTrace, traceEvents: readonly Types.Events.Event[],\n options: Types.Configuration.ParseOptions): void {\n this.#insights = new Map();\n\n const enabledInsightRunners = TraceProcessor.getEnabledInsightRunners(parsedTrace);\n\n const navigations = parsedTrace.Meta.mainFrameNavigations.filter(\n navigation => navigation.args.frame && navigation.args.data?.navigationId);\n\n // Check if there is a meaningful chunk of work happening prior to the first navigation.\n // If so, we run the insights on that initial bounds.\n // Otherwise, there are no navigations and we do a no-navigation insights pass on the entire trace.\n if (navigations.length) {\n const bounds = Helpers.Timing.traceWindowFromMicroSeconds(parsedTrace.Meta.traceBounds.min, navigations[0].ts);\n // When using \"Record and reload\" option, it typically takes ~5ms. So use 50ms to be safe.\n const threshold = Helpers.Timing.milliToMicro(50 as Types.Timing.Milli);\n if (bounds.range > threshold) {\n const context: Insights.Types.InsightSetContext = {\n bounds,\n frameId: parsedTrace.Meta.mainFrameId,\n };\n this.#computeInsightSet(this.#insights, parsedTrace, enabledInsightRunners, context, options);\n }\n // If threshold is not met, then the very beginning of the trace is ignored by the insights engine.\n } else {\n const context: Insights.Types.InsightSetContext = {\n bounds: parsedTrace.Meta.traceBounds,\n frameId: parsedTrace.Meta.mainFrameId,\n };\n this.#computeInsightSet(this.#insights, parsedTrace, enabledInsightRunners, context, options);\n }\n\n // Now run the insights for each navigation in isolation.\n for (const [i, navigation] of navigations.entries()) {\n // The above filter guarantees these are present.\n const frameId = navigation.args.frame;\n const navigationId = navigation.args.data?.navigationId as string;\n\n // The lantern sub-context is optional on InsightSetContext, so not setting it is OK.\n // This is also a hedge against an error inside Lantern resulting in breaking the entire performance panel.\n // Additionally, many trace fixtures are too old to be processed by Lantern.\n let lantern;\n try {\n lantern = this.#createLanternContext(parsedTrace, traceEvents, frameId, navigationId);\n } catch (e) {\n // Don't allow an error in constructing the Lantern graphs to break the rest of the trace processor.\n // Log unexpected errors, but suppress anything that occurs from a trace being too old.\n // Otherwise tests using old fixtures become way too noisy.\n const expectedErrors = [\n 'mainDocumentRequest not found',\n 'missing metric scores for main frame',\n 'missing metric: FCP',\n 'missing metric: LCP',\n 'No network requests found in trace',\n 'Trace is too old',\n ];\n if (!(e instanceof Lantern.Core.LanternError)) {\n // If this wasn't a managed LanternError, the stack trace is likely needed for debugging.\n console.error(e);\n } else if (!expectedErrors.some(err => e.message === err)) {\n // To reduce noise from tests, only print errors that are not expected to occur because a trace is\n // too old (for which there is no single check).\n console.error(e);\n }\n }\n\n const min = navigation.ts;\n const max = i + 1 < navigations.length ? navigations[i + 1].ts : parsedTrace.Meta.traceBounds.max;\n const bounds = Helpers.Timing.traceWindowFromMicroSeconds(min, max);\n const context: Insights.Types.InsightSetContext = {\n bounds,\n frameId,\n navigation,\n navigationId,\n lantern,\n };\n\n this.#computeInsightSet(this.#insights, parsedTrace, enabledInsightRunners, context, options);\n }\n }\n}\n\n/**\n * Some Handlers need data provided by others. Dependencies of a handler handler are\n * declared in the `deps` field.\n * @returns A map from trace event handler name to trace event handler whose entries\n * iterate in such a way that each handler is visited after its dependencies.\n */\nexport function sortHandlers(traceHandlers: Partial<{[key in Handlers.Types.HandlerName]: Handlers.Types.Handler}>):\n Map<Handlers.Types.HandlerName, Handlers.Types.Handler> {\n const sortedMap = new Map<Handlers.Types.HandlerName, Handlers.Types.Handler>();\n const visited = new Set<Handlers.Types.HandlerName>();\n const visitHandler = (handlerName: Handlers.Types.HandlerName): void => {\n if (sortedMap.has(handlerName)) {\n return;\n }\n if (visited.has(handlerName)) {\n let stackPath = '';\n for (const handler of visited) {\n if (stackPath || handler === handlerName) {\n stackPath += `${handler}->`;\n }\n }\n stackPath += handlerName;\n throw new Error(`Found dependency cycle in trace event handlers: ${stackPath}`);\n }\n visited.add(handlerName);\n const handler = traceHandlers[handlerName];\n if (!handler) {\n return;\n }\n const deps = handler.deps?.();\n if (deps) {\n deps.forEach(visitHandler);\n }\n sortedMap.set(handlerName, handler);\n };\n\n for (const handlerName of Object.keys(traceHandlers)) {\n visitHandler(handlerName as Handlers.Types.HandlerName);\n }\n return sortedMap;\n}\n"]}
|
|
@@ -28,7 +28,7 @@ export declare function extractRelatedDOMNodesFromEvent(modelData: Handlers.Type
|
|
|
28
28
|
* Takes a set of Protocol.DOM.BackendNodeId ids and will return a map of NodeId=>DOMNode.
|
|
29
29
|
* Results are cached based on 1) the provided ParsedTrace and 2) the provided set of IDs.
|
|
30
30
|
*/
|
|
31
|
-
export declare function domNodesForMultipleBackendNodeIds(modelData: Handlers.Types.ParsedTrace, nodeIds:
|
|
31
|
+
export declare function domNodesForMultipleBackendNodeIds(modelData: Handlers.Types.ParsedTrace, nodeIds: Protocol.DOM.BackendNodeId[]): Promise<Map<Protocol.DOM.BackendNodeId, SDK.DOMModel.DOMNode | null>>;
|
|
32
32
|
export interface LayoutShiftSource {
|
|
33
33
|
previousRect: DOMRect;
|
|
34
34
|
currentRect: DOMRect;
|
|
@@ -73,13 +73,13 @@ export function nodeIdsForEvent(modelData, event) {
|
|
|
73
73
|
// done the work to build the relationship between a DecodeImage event and
|
|
74
74
|
// the corresponding PaintImage event.
|
|
75
75
|
const paintImageEvent = modelData.ImagePainting.paintImageForEvent.get(event);
|
|
76
|
-
if (
|
|
76
|
+
if (typeof paintImageEvent?.args.data.nodeId !== 'undefined') {
|
|
77
77
|
foundIds.add(paintImageEvent.args.data.nodeId);
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
else if (Types.Events.isDrawLazyPixelRef(event) && event.args?.LazyPixelRef) {
|
|
81
81
|
const paintImageEvent = modelData.ImagePainting.paintImageByDrawLazyPixelRef.get(event.args.LazyPixelRef);
|
|
82
|
-
if (
|
|
82
|
+
if (typeof paintImageEvent?.args.data.nodeId !== 'undefined') {
|
|
83
83
|
foundIds.add(paintImageEvent.args.data.nodeId);
|
|
84
84
|
}
|
|
85
85
|
}
|
|
@@ -98,7 +98,7 @@ export function nodeIdsForEvent(modelData, event) {
|
|
|
98
98
|
export async function extractRelatedDOMNodesFromEvent(modelData, event) {
|
|
99
99
|
const nodeIds = nodeIdsForEvent(modelData, event);
|
|
100
100
|
if (nodeIds.size) {
|
|
101
|
-
return domNodesForMultipleBackendNodeIds(modelData, Array.from(nodeIds));
|
|
101
|
+
return await domNodesForMultipleBackendNodeIds(modelData, Array.from(nodeIds));
|
|
102
102
|
}
|
|
103
103
|
return null;
|
|
104
104
|
}
|