@paulirish/trace_engine 0.0.39 → 0.0.41
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/DevToolsPath.d.ts +30 -9
- package/core/platform/DevToolsPath.js +21 -0
- package/core/platform/DevToolsPath.js.map +1 -1
- package/core/platform/MapUtilities.js +1 -1
- package/core/platform/MapUtilities.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/devtools_entrypoint-bundle-typescript-tsconfig.json +2 -1
- package/core/platform/platform-tsconfig.json +2 -1
- package/generated/protocol.d.ts +203 -73
- package/locales/af.json +26 -2
- package/locales/am.json +27 -3
- package/locales/ar.json +26 -2
- package/locales/as.json +26 -2
- package/locales/az.json +26 -2
- package/locales/be.json +26 -2
- package/locales/bg.json +26 -2
- package/locales/bn.json +26 -2
- package/locales/bs.json +26 -2
- package/locales/ca.json +26 -2
- package/locales/cs.json +26 -2
- package/locales/cy.json +26 -2
- package/locales/da.json +26 -2
- package/locales/de.json +26 -2
- package/locales/el.json +26 -2
- package/locales/en-GB.json +26 -2
- package/locales/en-US.json +20 -2
- package/locales/en-XL.json +20 -2
- package/locales/es-419.json +26 -2
- package/locales/es.json +26 -2
- package/locales/et.json +26 -2
- package/locales/eu.json +26 -2
- package/locales/fa.json +26 -2
- package/locales/fi.json +26 -2
- package/locales/fil.json +26 -2
- package/locales/fr-CA.json +26 -2
- package/locales/fr.json +26 -2
- package/locales/gl.json +26 -2
- package/locales/gu.json +26 -2
- package/locales/he.json +26 -2
- package/locales/hi.json +26 -2
- package/locales/hr.json +26 -2
- package/locales/hu.json +26 -2
- package/locales/hy.json +26 -2
- package/locales/id.json +26 -2
- package/locales/is.json +26 -2
- package/locales/it.json +26 -2
- package/locales/ja.json +26 -2
- package/locales/ka.json +26 -2
- package/locales/kk.json +26 -2
- package/locales/km.json +26 -2
- package/locales/kn.json +26 -2
- package/locales/ko.json +26 -2
- package/locales/ky.json +26 -2
- package/locales/lo.json +26 -2
- package/locales/lt.json +26 -2
- package/locales/lv.json +26 -2
- package/locales/mk.json +26 -2
- package/locales/ml.json +26 -2
- package/locales/mn.json +27 -3
- package/locales/mr.json +26 -2
- package/locales/ms.json +26 -2
- package/locales/my.json +26 -2
- package/locales/ne.json +26 -2
- package/locales/nl.json +26 -2
- package/locales/no.json +26 -2
- package/locales/or.json +27 -3
- package/locales/pa.json +26 -2
- package/locales/pl.json +26 -2
- package/locales/pt-PT.json +26 -2
- package/locales/pt.json +26 -2
- package/locales/ro.json +26 -2
- package/locales/ru.json +26 -2
- package/locales/si.json +26 -2
- package/locales/sk.json +26 -2
- package/locales/sl.json +26 -2
- package/locales/sq.json +26 -2
- package/locales/sr-Latn.json +26 -2
- package/locales/sr.json +26 -2
- package/locales/sv.json +26 -2
- package/locales/sw.json +26 -2
- package/locales/ta.json +26 -2
- package/locales/te.json +26 -2
- package/locales/th.json +26 -2
- package/locales/tr.json +26 -2
- package/locales/uk.json +26 -2
- package/locales/ur.json +26 -2
- package/locales/uz.json +26 -2
- package/locales/vi.json +26 -2
- package/locales/zh-HK.json +26 -2
- package/locales/zh-TW.json +26 -2
- package/locales/zh.json +26 -2
- package/locales/zu.json +26 -2
- package/models/cpu_profile/ProfileTreeModel.js +0 -2
- package/models/cpu_profile/ProfileTreeModel.js.map +1 -1
- package/models/cpu_profile/cpu_profile-tsconfig.json +2 -1
- package/models/cpu_profile/devtools_entrypoint-bundle-typescript-tsconfig.json +2 -1
- package/models/trace/LanternComputationData.js +1 -1
- package/models/trace/LanternComputationData.js.map +1 -1
- package/models/trace/ModelImpl.d.ts +6 -6
- package/models/trace/ModelImpl.js +1 -0
- package/models/trace/ModelImpl.js.map +1 -1
- package/models/trace/Processor.d.ts +6 -0
- package/models/trace/Processor.js +90 -9
- package/models/trace/Processor.js.map +1 -1
- package/models/trace/devtools_entrypoint-bundle-typescript-tsconfig.json +2 -1
- package/models/trace/extras/StackTraceForEvent.d.ts +12 -0
- package/models/trace/extras/StackTraceForEvent.js +163 -0
- package/models/trace/extras/StackTraceForEvent.js.map +1 -0
- package/models/trace/extras/ThirdParties.d.ts +7 -4
- package/models/trace/extras/ThirdParties.js +56 -65
- package/models/trace/extras/ThirdParties.js.map +1 -1
- package/models/trace/extras/TraceTree.js +8 -8
- package/models/trace/extras/TraceTree.js.map +1 -1
- package/models/trace/extras/devtools_entrypoint-bundle-typescript-tsconfig.json +2 -1
- package/models/trace/extras/extras-tsconfig.json +3 -2
- package/models/trace/extras/extras.js.map +1 -1
- package/models/trace/handlers/AnimationFramesHandler.d.ts +11 -0
- package/models/trace/handlers/AnimationFramesHandler.js +102 -0
- package/models/trace/handlers/AnimationFramesHandler.js.map +1 -0
- package/models/trace/handlers/AsyncJSCallsHandler.d.ts +15 -0
- package/models/trace/handlers/AsyncJSCallsHandler.js +153 -0
- package/models/trace/handlers/AsyncJSCallsHandler.js.map +1 -0
- package/models/trace/handlers/DOMStatsHandler.d.ts +8 -0
- package/models/trace/handlers/DOMStatsHandler.js +22 -0
- package/models/trace/handlers/DOMStatsHandler.js.map +1 -0
- package/models/trace/handlers/ExtensionTraceDataHandler.d.ts +80 -2
- package/models/trace/handlers/ExtensionTraceDataHandler.js +163 -13
- package/models/trace/handlers/ExtensionTraceDataHandler.js.map +1 -1
- package/models/trace/handlers/FlowsHandler.js +47 -55
- package/models/trace/handlers/FlowsHandler.js.map +1 -1
- package/models/trace/handlers/InitiatorsHandler.d.ts +11 -0
- package/models/trace/handlers/InitiatorsHandler.js +33 -25
- package/models/trace/handlers/InitiatorsHandler.js.map +1 -1
- package/models/trace/handlers/LargestImagePaintHandler.d.ts +0 -2
- package/models/trace/handlers/LargestImagePaintHandler.js +27 -24
- package/models/trace/handlers/LargestImagePaintHandler.js.map +1 -1
- package/models/trace/handlers/LayoutShiftsHandler.d.ts +2 -2
- package/models/trace/handlers/LayoutShiftsHandler.js +3 -2
- package/models/trace/handlers/LayoutShiftsHandler.js.map +1 -1
- package/models/trace/handlers/MetaHandler.d.ts +2 -2
- package/models/trace/handlers/MetaHandler.js +1 -1
- package/models/trace/handlers/MetaHandler.js.map +1 -1
- package/models/trace/handlers/ModelHandlers.d.ts +4 -1
- package/models/trace/handlers/ModelHandlers.js +4 -1
- package/models/trace/handlers/ModelHandlers.js.map +1 -1
- package/models/trace/handlers/NetworkRequestsHandler.d.ts +2 -0
- package/models/trace/handlers/NetworkRequestsHandler.js +21 -0
- package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -1
- package/models/trace/handlers/PageLoadMetricsHandler.d.ts +2 -2
- package/models/trace/handlers/PageLoadMetricsHandler.js +9 -9
- package/models/trace/handlers/PageLoadMetricsHandler.js.map +1 -1
- package/models/trace/handlers/RendererHandler.d.ts +4 -0
- package/models/trace/handlers/RendererHandler.js +33 -2
- package/models/trace/handlers/RendererHandler.js.map +1 -1
- package/models/trace/handlers/SamplesHandler.d.ts +2 -2
- package/models/trace/handlers/SamplesHandler.js +3 -3
- package/models/trace/handlers/SamplesHandler.js.map +1 -1
- package/models/trace/handlers/ServerTimingsHandler.js +2 -2
- package/models/trace/handlers/ServerTimingsHandler.js.map +1 -1
- package/models/trace/handlers/Threads.d.ts +1 -0
- package/models/trace/handlers/Threads.js +8 -0
- package/models/trace/handlers/Threads.js.map +1 -1
- package/models/trace/handlers/UserInteractionsHandler.js +5 -6
- package/models/trace/handlers/UserInteractionsHandler.js.map +1 -1
- package/models/trace/handlers/UserTimingsHandler.d.ts +1 -1
- package/models/trace/handlers/UserTimingsHandler.js +1 -1
- package/models/trace/handlers/UserTimingsHandler.js.map +1 -1
- package/models/trace/handlers/WarningsHandler.js +2 -2
- package/models/trace/handlers/WarningsHandler.js.map +1 -1
- package/models/trace/handlers/devtools_entrypoint-bundle-typescript-tsconfig.json +2 -1
- package/models/trace/handlers/handlers-tsconfig.json +9 -1
- package/models/trace/handlers/handlers.d.ts +1 -0
- package/models/trace/handlers/handlers.js +1 -0
- package/models/trace/handlers/handlers.js.map +1 -1
- package/models/trace/handlers/helpers.d.ts +19 -0
- package/models/trace/handlers/helpers.js +123 -0
- package/models/trace/handlers/helpers.js.map +1 -0
- package/models/trace/helpers/SamplesIntegrator.js +2 -2
- package/models/trace/helpers/SamplesIntegrator.js.map +1 -1
- package/models/trace/helpers/SyntheticEvents.js +1 -1
- package/models/trace/helpers/SyntheticEvents.js.map +1 -1
- package/models/trace/helpers/Timing.d.ts +5 -6
- package/models/trace/helpers/Timing.js +22 -31
- package/models/trace/helpers/Timing.js.map +1 -1
- package/models/trace/helpers/Trace.d.ts +24 -10
- package/models/trace/helpers/Trace.js +53 -6
- package/models/trace/helpers/Trace.js.map +1 -1
- package/models/trace/helpers/TreeHelpers.d.ts +0 -31
- package/models/trace/helpers/TreeHelpers.js +1 -142
- package/models/trace/helpers/TreeHelpers.js.map +1 -1
- package/models/trace/helpers/devtools_entrypoint-bundle-typescript-tsconfig.json +2 -1
- package/models/trace/helpers/helpers-tsconfig.json +2 -1
- package/models/trace/insights/CLSCulprits.d.ts +9 -0
- package/models/trace/insights/CLSCulprits.js +2 -3
- package/models/trace/insights/CLSCulprits.js.map +1 -1
- package/models/trace/insights/Common.d.ts +38 -1
- package/models/trace/insights/Common.js +123 -0
- package/models/trace/insights/Common.js.map +1 -1
- package/models/trace/insights/DOMSize.d.ts +19 -0
- package/models/trace/insights/DOMSize.js +102 -0
- package/models/trace/insights/DOMSize.js.map +1 -0
- package/models/trace/insights/DocumentLatency.d.ts +10 -0
- package/models/trace/insights/DocumentLatency.js +2 -2
- package/models/trace/insights/DocumentLatency.js.map +1 -1
- package/models/trace/insights/FontDisplay.d.ts +8 -0
- package/models/trace/insights/FontDisplay.js +2 -2
- package/models/trace/insights/FontDisplay.js.map +1 -1
- package/models/trace/insights/ImageDelivery.d.ts +54 -4
- package/models/trace/insights/ImageDelivery.js +77 -7
- package/models/trace/insights/ImageDelivery.js.map +1 -1
- package/models/trace/insights/InteractionToNextPaint.d.ts +10 -0
- package/models/trace/insights/InteractionToNextPaint.js +1 -1
- package/models/trace/insights/InteractionToNextPaint.js.map +1 -1
- package/models/trace/insights/LCPDiscovery.d.ts +10 -0
- package/models/trace/insights/LCPDiscovery.js +3 -3
- package/models/trace/insights/LCPDiscovery.js.map +1 -1
- package/models/trace/insights/LCPPhases.d.ts +11 -0
- package/models/trace/insights/LCPPhases.js +8 -8
- package/models/trace/insights/LCPPhases.js.map +1 -1
- package/models/trace/insights/Models.d.ts +1 -0
- package/models/trace/insights/Models.js +1 -0
- package/models/trace/insights/Models.js.map +1 -1
- package/models/trace/insights/RenderBlocking.d.ts +10 -0
- package/models/trace/insights/RenderBlocking.js +1 -1
- package/models/trace/insights/RenderBlocking.js.map +1 -1
- package/models/trace/insights/SlowCSSSelector.d.ts +10 -0
- package/models/trace/insights/SlowCSSSelector.js +1 -1
- package/models/trace/insights/SlowCSSSelector.js.map +1 -1
- package/models/trace/insights/Statistics.d.ts +14 -0
- package/models/trace/insights/Statistics.js +86 -0
- package/models/trace/insights/Statistics.js.map +1 -0
- package/models/trace/insights/ThirdParties.d.ts +11 -2
- package/models/trace/insights/ThirdParties.js +6 -5
- package/models/trace/insights/ThirdParties.js.map +1 -1
- package/models/trace/insights/Viewport.d.ts +8 -0
- package/models/trace/insights/Viewport.js +3 -3
- package/models/trace/insights/Viewport.js.map +1 -1
- package/models/trace/insights/devtools_entrypoint-bundle-typescript-tsconfig.json +2 -1
- package/models/trace/insights/insights-tsconfig.json +4 -1
- package/models/trace/insights/insights.d.ts +1 -0
- package/models/trace/insights/insights.js +1 -0
- package/models/trace/insights/insights.js.map +1 -1
- package/models/trace/insights/types.d.ts +4 -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 -3
- package/models/trace/lantern/core/NetworkAnalyzer.js.map +1 -1
- package/models/trace/lantern/core/core-tsconfig.json +2 -1
- package/models/trace/lantern/core/devtools_entrypoint-bundle-typescript-tsconfig.json +2 -1
- package/models/trace/lantern/devtools_entrypoint-bundle-typescript-tsconfig.json +2 -1
- package/models/trace/lantern/graph/PageDependencyGraph.js +0 -1
- package/models/trace/lantern/graph/PageDependencyGraph.js.map +1 -1
- package/models/trace/lantern/graph/devtools_entrypoint-bundle-typescript-tsconfig.json +2 -1
- package/models/trace/lantern/graph/graph-tsconfig.json +2 -1
- package/models/trace/lantern/lantern-tsconfig.json +2 -1
- package/models/trace/lantern/metrics/devtools_entrypoint-bundle-typescript-tsconfig.json +2 -1
- package/models/trace/lantern/metrics/metrics-tsconfig.json +2 -1
- package/models/trace/lantern/simulation/DNSCache.d.ts +2 -2
- package/models/trace/lantern/simulation/DNSCache.js.map +1 -1
- package/models/trace/lantern/simulation/devtools_entrypoint-bundle-typescript-tsconfig.json +2 -1
- package/models/trace/lantern/simulation/simulation-tsconfig.json +2 -1
- package/models/trace/lantern/types/Lantern.d.ts +10 -10
- package/models/trace/lantern/types/Lantern.js.map +1 -1
- package/models/trace/lantern/types/devtools_entrypoint-bundle-typescript-tsconfig.json +2 -1
- package/models/trace/lantern/types/types-tsconfig.json +2 -1
- package/models/trace/root-causes/LayoutShift.d.ts +6 -6
- package/models/trace/root-causes/LayoutShift.js +1 -1
- package/models/trace/root-causes/LayoutShift.js.map +1 -1
- package/models/trace/root-causes/RootCauses.d.ts +2 -2
- package/models/trace/root-causes/RootCauses.js.map +1 -1
- package/models/trace/root-causes/devtools_entrypoint-bundle-typescript-tsconfig.json +2 -1
- package/models/trace/root-causes/root-causes-tsconfig.json +2 -1
- package/models/trace/trace-tsconfig.json +2 -1
- package/models/trace/types/Configuration.d.ts +2 -2
- package/models/trace/types/Configuration.js.map +1 -1
- package/models/trace/types/Extensions.d.ts +3 -3
- package/models/trace/types/Extensions.js.map +1 -1
- package/models/trace/types/File.d.ts +11 -11
- package/models/trace/types/File.js.map +1 -1
- package/models/trace/types/Timing.js.map +1 -1
- package/models/trace/types/TraceEvents.d.ts +107 -31
- package/models/trace/types/TraceEvents.js +34 -14
- package/models/trace/types/TraceEvents.js.map +1 -1
- package/models/trace/types/devtools_entrypoint-bundle-typescript-tsconfig.json +2 -1
- package/models/trace/types/types-tsconfig.json +2 -1
- package/package.json +1 -1
- package/test/test-trace-engine.mjs +8 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RenderBlocking.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/RenderBlocking.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 i18n from '../../../core/i18n/i18n.js';\nimport * as Protocol from '../../../generated/protocol.js';\nimport * as Handlers from '../handlers/handlers.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport type * as Lantern from '../lantern/lantern.js';\nimport type * as Types from '../types/types.js';\n\nimport {\n InsightCategory,\n type InsightModel,\n type InsightSetContext,\n type InsightSetContextWithNavigation,\n InsightWarning,\n type LanternContext,\n type RequiredData,\n} from './types.js';\n\nconst UIStrings = {\n /**\n * @description Title of an insight that provides the user with the list of network requests that blocked and therefore slowed down the page rendering and becoming visible to the user.\n */\n title: 'Render blocking requests',\n /**\n * @description Text to describe that there are requests blocking rendering, which may affect LCP.\n */\n description: 'Requests are blocking the page\\'s initial render, which may delay LCP. ' +\n '[Deferring or inlining](https://web.dev/learn/performance/understanding-the-critical-path#render-blocking_resources/) ' +\n 'can move these network requests out of the critical path.',\n};\n\nconst str_ = i18n.i18n.registerUIStrings('models/trace/insights/RenderBlocking.ts', UIStrings);\nconst i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);\n\nexport type RenderBlockingInsightModel = InsightModel<{\n renderBlockingRequests: Types.Events.SyntheticNetworkRequest[],\n requestIdToWastedMs?: Map<string, number>,\n}>;\n\n// Because of the way we detect blocking stylesheets, asynchronously loaded\n// CSS with link[rel=preload] and an onload handler (see https://github.com/filamentgroup/loadCSS)\n// can be falsely flagged as blocking. Therefore, ignore stylesheets that loaded fast enough\n// to possibly be non-blocking (and they have minimal impact anyway).\nconst MINIMUM_WASTED_MS = 50;\n\nexport function deps(): ['NetworkRequests', 'PageLoadMetrics', 'LargestImagePaint'] {\n return ['NetworkRequests', 'PageLoadMetrics', 'LargestImagePaint'];\n}\n\n/**\n * Given a simulation's nodeTimings, return an object with the nodes/timing keyed by network URL\n */\nfunction getNodesAndTimingByRequestId(nodeTimings: Lantern.Simulation.Result['nodeTimings']):\n Map<string, {node: Lantern.Graph.Node, nodeTiming: Lantern.Types.Simulation.NodeTiming}> {\n const requestIdToNode =\n new Map<string, {node: Lantern.Graph.Node, nodeTiming: Lantern.Types.Simulation.NodeTiming}>();\n\n for (const [node, nodeTiming] of nodeTimings) {\n if (node.type !== 'network') {\n continue;\n }\n\n requestIdToNode.set(node.request.requestId, {node, nodeTiming});\n }\n\n return requestIdToNode;\n}\n\nfunction estimateSavingsWithGraphs(\n deferredIds: Set<string>, lanternContext: LanternContext): Types.Timing.MilliSeconds {\n const simulator = lanternContext.simulator;\n const fcpGraph = lanternContext.metrics.firstContentfulPaint.optimisticGraph;\n const {nodeTimings} = lanternContext.simulator.simulate(fcpGraph);\n const adjustedNodeTimings = new Map(nodeTimings);\n\n const totalChildNetworkBytes = 0;\n const minimalFCPGraph = fcpGraph.cloneWithRelationships(node => {\n // If a node can be deferred, exclude it from the new FCP graph\n const canDeferRequest = deferredIds.has(node.id);\n return !canDeferRequest;\n });\n\n if (minimalFCPGraph.type !== 'network') {\n throw new Error('minimalFCPGraph not a NetworkNode');\n }\n\n // Recalculate the \"before\" time based on our adjusted node timings.\n const estimateBeforeInline = Math.max(...Array.from(\n Array.from(adjustedNodeTimings).map(timing => timing[1].endTime),\n ));\n\n // Add the inlined bytes to the HTML response\n const originalTransferSize = minimalFCPGraph.request.transferSize;\n const safeTransferSize = originalTransferSize || 0;\n minimalFCPGraph.request.transferSize = safeTransferSize + totalChildNetworkBytes;\n const estimateAfterInline = simulator.simulate(minimalFCPGraph).timeInMs;\n minimalFCPGraph.request.transferSize = originalTransferSize;\n return Math.round(Math.max(estimateBeforeInline - estimateAfterInline, 0)) as Types.Timing.MilliSeconds;\n}\n\nfunction hasImageLCP(parsedTrace: RequiredData<typeof deps>, context: InsightSetContextWithNavigation): boolean {\n return parsedTrace.LargestImagePaint.lcpRequestByNavigation.get(context.navigation) !== undefined;\n}\n\nfunction computeSavings(\n parsedTrace: RequiredData<typeof deps>, context: InsightSetContextWithNavigation,\n renderBlockingRequests: Types.Events.SyntheticNetworkRequest[]):\n Pick<RenderBlockingInsightModel, 'metricSavings'|'requestIdToWastedMs'>|undefined {\n if (!context.lantern) {\n return;\n }\n\n const nodesAndTimingsByRequestId =\n getNodesAndTimingByRequestId(context.lantern.metrics.firstContentfulPaint.optimisticEstimate.nodeTimings);\n\n const metricSavings = {FCP: 0 as Types.Timing.MilliSeconds, LCP: 0 as Types.Timing.MilliSeconds};\n const requestIdToWastedMs = new Map<string, number>();\n const deferredNodeIds = new Set<string>();\n for (const request of renderBlockingRequests) {\n const nodeAndTiming = nodesAndTimingsByRequestId.get(request.args.data.requestId);\n if (!nodeAndTiming) {\n continue;\n }\n\n const {node, nodeTiming} = nodeAndTiming;\n\n // Mark this node and all its dependents as deferrable\n node.traverse(node => deferredNodeIds.add(node.id));\n\n // \"wastedMs\" is the download time of the network request, responseReceived - requestSent\n const wastedMs = Math.round(nodeTiming.duration);\n if (wastedMs < MINIMUM_WASTED_MS) {\n continue;\n }\n\n requestIdToWastedMs.set(node.id, wastedMs);\n }\n\n if (requestIdToWastedMs.size) {\n metricSavings.FCP = estimateSavingsWithGraphs(deferredNodeIds, context.lantern);\n\n // In most cases, render blocking resources only affect LCP if LCP isn't an image.\n if (!hasImageLCP(parsedTrace, context)) {\n metricSavings.LCP = metricSavings.FCP;\n }\n }\n\n return {metricSavings, requestIdToWastedMs};\n}\n\nfunction finalize(partialModel: Omit<RenderBlockingInsightModel, 'title'|'description'|'category'|'shouldShow'>):\n RenderBlockingInsightModel {\n return {\n title: i18nString(UIStrings.title),\n description: i18nString(UIStrings.description),\n category: InsightCategory.LCP,\n shouldShow: partialModel.renderBlockingRequests.length > 0,\n ...partialModel,\n };\n}\n\nexport function generateInsight(\n parsedTrace: RequiredData<typeof deps>, context: InsightSetContext): RenderBlockingInsightModel {\n if (!context.navigation) {\n return finalize({\n renderBlockingRequests: [],\n });\n }\n\n const firstPaintTs = parsedTrace.PageLoadMetrics.metricScoresByFrameId.get(context.frameId)\n ?.get(context.navigationId)\n ?.get(Handlers.ModelHandlers.PageLoadMetrics.MetricName.FP)\n ?.event?.ts;\n if (!firstPaintTs) {\n return finalize({\n renderBlockingRequests: [],\n warnings: [InsightWarning.NO_FP],\n });\n }\n\n let renderBlockingRequests: Types.Events.SyntheticNetworkRequest[] = [];\n for (const req of parsedTrace.NetworkRequests.byTime) {\n if (req.args.data.frame !== context.frameId) {\n continue;\n }\n\n if (!Helpers.Network.isSyntheticNetworkRequestEventRenderBlocking(req)) {\n continue;\n }\n\n if (req.args.data.syntheticData.finishTime > firstPaintTs) {\n continue;\n }\n\n // If a request is marked `in_body_parser_blocking` it should only be considered render blocking if it is a\n // high enough priority. Some requests (e.g. scripts) are not marked as high priority if they are fetched\n // after a non-preloaded image. (See \"early\" definition in https://web.dev/articles/fetch-priority)\n //\n // There are edge cases and exceptions (e.g. priority hints) but this gives us the best approximation\n // of render blocking resources in the document body.\n if (req.args.data.renderBlocking === 'in_body_parser_blocking') {\n const priority = req.args.data.priority;\n const isScript = req.args.data.resourceType === Protocol.Network.ResourceType.Script;\n const isBlockingScript = isScript && priority === Protocol.Network.ResourcePriority.High;\n if (priority !== Protocol.Network.ResourcePriority.VeryHigh && !isBlockingScript) {\n continue;\n }\n }\n\n const navigation =\n Helpers.Trace.getNavigationForTraceEvent(req, context.frameId, parsedTrace.Meta.navigationsByFrameId);\n if (navigation === context.navigation) {\n renderBlockingRequests.push(req);\n }\n }\n\n const savings = computeSavings(parsedTrace, context, renderBlockingRequests);\n\n // Sort by request duration for insights.\n renderBlockingRequests = renderBlockingRequests.sort((a, b) => {\n return b.dur - a.dur;\n });\n\n return finalize({\n relatedEvents: renderBlockingRequests,\n renderBlockingRequests,\n ...savings,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"RenderBlocking.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/RenderBlocking.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 i18n from '../../../core/i18n/i18n.js';\nimport * as Protocol from '../../../generated/protocol.js';\nimport * as Handlers from '../handlers/handlers.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport type * as Lantern from '../lantern/lantern.js';\nimport type * as Types from '../types/types.js';\n\nimport {\n InsightCategory,\n type InsightModel,\n type InsightSetContext,\n type InsightSetContextWithNavigation,\n InsightWarning,\n type LanternContext,\n type RequiredData,\n} from './types.js';\n\nexport const UIStrings = {\n /**\n * @description Title of an insight that provides the user with the list of network requests that blocked and therefore slowed down the page rendering and becoming visible to the user.\n */\n title: 'Render blocking requests',\n /**\n * @description Text to describe that there are requests blocking rendering, which may affect LCP.\n */\n description: 'Requests are blocking the page\\'s initial render, which may delay LCP. ' +\n '[Deferring or inlining](https://web.dev/learn/performance/understanding-the-critical-path#render-blocking_resources/) ' +\n 'can move these network requests out of the critical path.',\n};\n\nconst str_ = i18n.i18n.registerUIStrings('models/trace/insights/RenderBlocking.ts', UIStrings);\nconst i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);\n\nexport type RenderBlockingInsightModel = InsightModel<{\n renderBlockingRequests: Types.Events.SyntheticNetworkRequest[],\n requestIdToWastedMs?: Map<string, number>,\n}>;\n\n// Because of the way we detect blocking stylesheets, asynchronously loaded\n// CSS with link[rel=preload] and an onload handler (see https://github.com/filamentgroup/loadCSS)\n// can be falsely flagged as blocking. Therefore, ignore stylesheets that loaded fast enough\n// to possibly be non-blocking (and they have minimal impact anyway).\nconst MINIMUM_WASTED_MS = 50;\n\nexport function deps(): ['NetworkRequests', 'PageLoadMetrics', 'LargestImagePaint'] {\n return ['NetworkRequests', 'PageLoadMetrics', 'LargestImagePaint'];\n}\n\n/**\n * Given a simulation's nodeTimings, return an object with the nodes/timing keyed by network URL\n */\nfunction getNodesAndTimingByRequestId(nodeTimings: Lantern.Simulation.Result['nodeTimings']):\n Map<string, {node: Lantern.Graph.Node, nodeTiming: Lantern.Types.Simulation.NodeTiming}> {\n const requestIdToNode =\n new Map<string, {node: Lantern.Graph.Node, nodeTiming: Lantern.Types.Simulation.NodeTiming}>();\n\n for (const [node, nodeTiming] of nodeTimings) {\n if (node.type !== 'network') {\n continue;\n }\n\n requestIdToNode.set(node.request.requestId, {node, nodeTiming});\n }\n\n return requestIdToNode;\n}\n\nfunction estimateSavingsWithGraphs(\n deferredIds: Set<string>, lanternContext: LanternContext): Types.Timing.MilliSeconds {\n const simulator = lanternContext.simulator;\n const fcpGraph = lanternContext.metrics.firstContentfulPaint.optimisticGraph;\n const {nodeTimings} = lanternContext.simulator.simulate(fcpGraph);\n const adjustedNodeTimings = new Map(nodeTimings);\n\n const totalChildNetworkBytes = 0;\n const minimalFCPGraph = fcpGraph.cloneWithRelationships(node => {\n // If a node can be deferred, exclude it from the new FCP graph\n const canDeferRequest = deferredIds.has(node.id);\n return !canDeferRequest;\n });\n\n if (minimalFCPGraph.type !== 'network') {\n throw new Error('minimalFCPGraph not a NetworkNode');\n }\n\n // Recalculate the \"before\" time based on our adjusted node timings.\n const estimateBeforeInline = Math.max(...Array.from(\n Array.from(adjustedNodeTimings).map(timing => timing[1].endTime),\n ));\n\n // Add the inlined bytes to the HTML response\n const originalTransferSize = minimalFCPGraph.request.transferSize;\n const safeTransferSize = originalTransferSize || 0;\n minimalFCPGraph.request.transferSize = safeTransferSize + totalChildNetworkBytes;\n const estimateAfterInline = simulator.simulate(minimalFCPGraph).timeInMs;\n minimalFCPGraph.request.transferSize = originalTransferSize;\n return Math.round(Math.max(estimateBeforeInline - estimateAfterInline, 0)) as Types.Timing.MilliSeconds;\n}\n\nfunction hasImageLCP(parsedTrace: RequiredData<typeof deps>, context: InsightSetContextWithNavigation): boolean {\n return parsedTrace.LargestImagePaint.lcpRequestByNavigation.get(context.navigation) !== undefined;\n}\n\nfunction computeSavings(\n parsedTrace: RequiredData<typeof deps>, context: InsightSetContextWithNavigation,\n renderBlockingRequests: Types.Events.SyntheticNetworkRequest[]):\n Pick<RenderBlockingInsightModel, 'metricSavings'|'requestIdToWastedMs'>|undefined {\n if (!context.lantern) {\n return;\n }\n\n const nodesAndTimingsByRequestId =\n getNodesAndTimingByRequestId(context.lantern.metrics.firstContentfulPaint.optimisticEstimate.nodeTimings);\n\n const metricSavings = {FCP: 0 as Types.Timing.MilliSeconds, LCP: 0 as Types.Timing.MilliSeconds};\n const requestIdToWastedMs = new Map<string, number>();\n const deferredNodeIds = new Set<string>();\n for (const request of renderBlockingRequests) {\n const nodeAndTiming = nodesAndTimingsByRequestId.get(request.args.data.requestId);\n if (!nodeAndTiming) {\n continue;\n }\n\n const {node, nodeTiming} = nodeAndTiming;\n\n // Mark this node and all its dependents as deferrable\n node.traverse(node => deferredNodeIds.add(node.id));\n\n // \"wastedMs\" is the download time of the network request, responseReceived - requestSent\n const wastedMs = Math.round(nodeTiming.duration);\n if (wastedMs < MINIMUM_WASTED_MS) {\n continue;\n }\n\n requestIdToWastedMs.set(node.id, wastedMs);\n }\n\n if (requestIdToWastedMs.size) {\n metricSavings.FCP = estimateSavingsWithGraphs(deferredNodeIds, context.lantern);\n\n // In most cases, render blocking resources only affect LCP if LCP isn't an image.\n if (!hasImageLCP(parsedTrace, context)) {\n metricSavings.LCP = metricSavings.FCP;\n }\n }\n\n return {metricSavings, requestIdToWastedMs};\n}\n\nfunction finalize(partialModel: Omit<RenderBlockingInsightModel, 'title'|'description'|'category'|'shouldShow'>):\n RenderBlockingInsightModel {\n return {\n title: i18nString(UIStrings.title),\n description: i18nString(UIStrings.description),\n category: InsightCategory.LCP,\n shouldShow: partialModel.renderBlockingRequests.length > 0,\n ...partialModel,\n };\n}\n\nexport function generateInsight(\n parsedTrace: RequiredData<typeof deps>, context: InsightSetContext): RenderBlockingInsightModel {\n if (!context.navigation) {\n return finalize({\n renderBlockingRequests: [],\n });\n }\n\n const firstPaintTs = parsedTrace.PageLoadMetrics.metricScoresByFrameId.get(context.frameId)\n ?.get(context.navigationId)\n ?.get(Handlers.ModelHandlers.PageLoadMetrics.MetricName.FP)\n ?.event?.ts;\n if (!firstPaintTs) {\n return finalize({\n renderBlockingRequests: [],\n warnings: [InsightWarning.NO_FP],\n });\n }\n\n let renderBlockingRequests: Types.Events.SyntheticNetworkRequest[] = [];\n for (const req of parsedTrace.NetworkRequests.byTime) {\n if (req.args.data.frame !== context.frameId) {\n continue;\n }\n\n if (!Helpers.Network.isSyntheticNetworkRequestEventRenderBlocking(req)) {\n continue;\n }\n\n if (req.args.data.syntheticData.finishTime > firstPaintTs) {\n continue;\n }\n\n // If a request is marked `in_body_parser_blocking` it should only be considered render blocking if it is a\n // high enough priority. Some requests (e.g. scripts) are not marked as high priority if they are fetched\n // after a non-preloaded image. (See \"early\" definition in https://web.dev/articles/fetch-priority)\n //\n // There are edge cases and exceptions (e.g. priority hints) but this gives us the best approximation\n // of render blocking resources in the document body.\n if (req.args.data.renderBlocking === 'in_body_parser_blocking') {\n const priority = req.args.data.priority;\n const isScript = req.args.data.resourceType === Protocol.Network.ResourceType.Script;\n const isBlockingScript = isScript && priority === Protocol.Network.ResourcePriority.High;\n if (priority !== Protocol.Network.ResourcePriority.VeryHigh && !isBlockingScript) {\n continue;\n }\n }\n\n const navigation =\n Helpers.Trace.getNavigationForTraceEvent(req, context.frameId, parsedTrace.Meta.navigationsByFrameId);\n if (navigation === context.navigation) {\n renderBlockingRequests.push(req);\n }\n }\n\n const savings = computeSavings(parsedTrace, context, renderBlockingRequests);\n\n // Sort by request duration for insights.\n renderBlockingRequests = renderBlockingRequests.sort((a, b) => {\n return b.dur - a.dur;\n });\n\n return finalize({\n relatedEvents: renderBlockingRequests,\n renderBlockingRequests,\n ...savings,\n });\n}\n"]}
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import * as Types from '../types/types.js';
|
|
2
2
|
import { type InsightModel, type InsightSetContext, type RequiredData } from './types.js';
|
|
3
|
+
export declare const UIStrings: {
|
|
4
|
+
/**
|
|
5
|
+
*@description Title of an insight that provides details about slow CSS selectors.
|
|
6
|
+
*/
|
|
7
|
+
title: string;
|
|
8
|
+
/**
|
|
9
|
+
* @description Text to describe how to improve the performance of CSS selectors.
|
|
10
|
+
*/
|
|
11
|
+
description: string;
|
|
12
|
+
};
|
|
3
13
|
export declare function deps(): ['SelectorStats'];
|
|
4
14
|
export type SlowCSSSelectorInsightModel = InsightModel<{
|
|
5
15
|
totalElapsedMs: Types.Timing.MilliSeconds;
|
|
@@ -6,7 +6,7 @@ import * as Helpers from '../helpers/helpers.js';
|
|
|
6
6
|
import { SelectorTimingsKey } from '../types/TraceEvents.js';
|
|
7
7
|
import * as Types from '../types/types.js';
|
|
8
8
|
import { InsightCategory } from './types.js';
|
|
9
|
-
const UIStrings = {
|
|
9
|
+
export const UIStrings = {
|
|
10
10
|
/**
|
|
11
11
|
*@description Title of an insight that provides details about slow CSS selectors.
|
|
12
12
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SlowCSSSelector.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/SlowCSSSelector.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,IAAI,MAAM,4BAA4B,CAAC;AACnD,OAAO,KAAK,OAAO,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAsB,kBAAkB,EAAC,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EAAC,eAAe,EAA+D,MAAM,YAAY,CAAC;AAEzG,MAAM,SAAS,GAAG;
|
|
1
|
+
{"version":3,"file":"SlowCSSSelector.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/SlowCSSSelector.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,IAAI,MAAM,4BAA4B,CAAC;AACnD,OAAO,KAAK,OAAO,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAsB,kBAAkB,EAAC,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EAAC,eAAe,EAA+D,MAAM,YAAY,CAAC;AAEzG,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB;;OAEG;IACH,KAAK,EAAE,oBAAoB;IAE3B;;OAEG;IACH,WAAW,EACP,yUAAyU;CAC9U,CAAC;AAEF,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,0CAA0C,EAAE,SAAS,CAAC,CAAC;AAChG,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAEtE,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,eAAe,CAAC,CAAC;AAC3B,CAAC;AAUD,SAAS,sBAAsB,CAC3B,IAEE,EACF,OAA0B;IAC5B,MAAM,WAAW,GAAG,IAAI,GAAG,EAA0B,CAAC;IAEtD,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;QAClC,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC;YACpD,SAAS;QACX,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3D,SAAS;QACX,CAAC;QACD,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACnC,MAAM,GAAG,GAAG,MAAM,CAAC,kBAAkB,CAAC,QAAQ,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;YAChG,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACxC,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC7B,UAAU,CAAC,kBAAkB,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;gBAC7E,UAAU,CAAC,kBAAkB,CAAC,eAAe,CAAC,IAAI,MAAM,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;gBAC7F,UAAU,CAAC,kBAAkB,CAAC,aAAa,CAAC,IAAI,MAAM,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC;gBACzF,UAAU,CAAC,kBAAkB,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;YACrF,CAAC;iBAAM,CAAC;gBACN,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,EAAC,GAAG,MAAM,EAAC,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,QAAQ,CAAC,YAA8F;IAE9G,OAAO;QACL,KAAK,EAAE,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC;QAClC,WAAW,EAAE,UAAU,CAAC,SAAS,CAAC,WAAW,CAAC;QAC9C,QAAQ,EAAE,eAAe,CAAC,GAAG;QAC7B,UAAU,EAAE,YAAY,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,IAAI,YAAY,CAAC,gBAAgB,CAAC,MAAM,KAAK,CAAC;QAChG,GAAG,YAAY;KAChB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAC3B,WAAsC,EAAE,OAA0B;IACpE,MAAM,iBAAiB,GAAG,WAAW,CAAC,aAAa,CAAC;IAEpD,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,eAAe,GAAG,sBAAsB,CAAC,iBAAiB,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;IAEpG,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,IAAI,kBAAkB,GAAG,CAAC,CAAC;IAC3B,IAAI,eAAe,GAAG,CAAC,CAAC;IAExB,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;QAC3B,cAAc,IAAI,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACrD,kBAAkB,IAAI,MAAM,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC;QAC/D,eAAe,IAAI,MAAM,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,uBAAuB;IACvB,MAAM,eAAe,GAAG,CAAC,GAAG,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACzD,OAAO,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,yBAAyB;IACzB,MAAM,mBAAmB,GAAG,CAAC,GAAG,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC7D,OAAO,CAAC,CAAC,kBAAkB,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC;IACnF,CAAC,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC;QACd,0EAA0E;QAC1E,aAAa,EAAE,EAAE;QACjB,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,cAAc,GAAG,MAAM,CAAC;QAClE,kBAAkB;QAClB,eAAe;QACf,YAAY,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QACzC,gBAAgB,EAAE,mBAAmB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;KAClD,CAAC,CAAC;AACL,CAAC","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 i18n from '../../../core/i18n/i18n.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport {type SelectorTiming, SelectorTimingsKey} from '../types/TraceEvents.js';\nimport * as Types from '../types/types.js';\n\nimport {InsightCategory, type InsightModel, type InsightSetContext, type RequiredData} from './types.js';\n\nexport const UIStrings = {\n /**\n *@description Title of an insight that provides details about slow CSS selectors.\n */\n title: 'CSS Selector costs',\n\n /**\n * @description Text to describe how to improve the performance of CSS selectors.\n */\n description:\n 'If Recalculate Style costs remain high, selector optimization can reduce them. [Optimize the selectors](https://developer.chrome.com/docs/devtools/performance/selector-stats) with both high elapsed time and high slow-path %. Simpler selectors, fewer selectors, a smaller DOM, and a shallower DOM will all reduce matching costs.',\n};\n\nconst str_ = i18n.i18n.registerUIStrings('models/trace/insights/SlowCSSSelector.ts', UIStrings);\nconst i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);\n\nexport function deps(): ['SelectorStats'] {\n return ['SelectorStats'];\n}\n\nexport type SlowCSSSelectorInsightModel = InsightModel<{\n totalElapsedMs: Types.Timing.MilliSeconds,\n totalMatchAttempts: number,\n totalMatchCount: number,\n topElapsedMs: Types.Events.SelectorTiming[],\n topMatchAttempts: Types.Events.SelectorTiming[],\n}>;\n\nfunction aggregateSelectorStats(\n data: Map<Types.Events.UpdateLayoutTree, {\n timings: Types.Events.SelectorTiming[],\n }>,\n context: InsightSetContext): SelectorTiming[] {\n const selectorMap = new Map<String, SelectorTiming>();\n\n for (const [event, value] of data) {\n if (event.args.beginData?.frame !== context.frameId) {\n continue;\n }\n if (!Helpers.Timing.eventIsInBounds(event, context.bounds)) {\n continue;\n }\n for (const timing of value.timings) {\n const key = timing[SelectorTimingsKey.Selector] + '_' + timing[SelectorTimingsKey.StyleSheetId];\n const findTiming = selectorMap.get(key);\n if (findTiming !== undefined) {\n findTiming[SelectorTimingsKey.Elapsed] += timing[SelectorTimingsKey.Elapsed];\n findTiming[SelectorTimingsKey.FastRejectCount] += timing[SelectorTimingsKey.FastRejectCount];\n findTiming[SelectorTimingsKey.MatchAttempts] += timing[SelectorTimingsKey.MatchAttempts];\n findTiming[SelectorTimingsKey.MatchCount] += timing[SelectorTimingsKey.MatchCount];\n } else {\n selectorMap.set(key, {...timing});\n }\n }\n }\n\n return [...selectorMap.values()];\n}\n\nfunction finalize(partialModel: Omit<SlowCSSSelectorInsightModel, 'title'|'description'|'category'|'shouldShow'>):\n SlowCSSSelectorInsightModel {\n return {\n title: i18nString(UIStrings.title),\n description: i18nString(UIStrings.description),\n category: InsightCategory.ALL,\n shouldShow: partialModel.topElapsedMs.length !== 0 && partialModel.topMatchAttempts.length !== 0,\n ...partialModel,\n };\n}\n\nexport function generateInsight(\n parsedTrace: RequiredData<typeof deps>, context: InsightSetContext): SlowCSSSelectorInsightModel {\n const selectorStatsData = parsedTrace.SelectorStats;\n\n if (!selectorStatsData) {\n throw new Error('no selector stats data');\n }\n\n const selectorTimings = aggregateSelectorStats(selectorStatsData.dataForUpdateLayoutEvent, context);\n\n let totalElapsedUs = 0;\n let totalMatchAttempts = 0;\n let totalMatchCount = 0;\n\n selectorTimings.map(timing => {\n totalElapsedUs += timing[SelectorTimingsKey.Elapsed];\n totalMatchAttempts += timing[SelectorTimingsKey.MatchAttempts];\n totalMatchCount += timing[SelectorTimingsKey.MatchCount];\n });\n\n // sort by elapsed time\n const sortByElapsedMs = [...selectorTimings].sort((a, b) => {\n return b[SelectorTimingsKey.Elapsed] - a[SelectorTimingsKey.Elapsed];\n });\n\n // sort by match attempts\n const sortByMatchAttempts = [...selectorTimings].sort((a, b) => {\n return b[SelectorTimingsKey.MatchAttempts] - a[SelectorTimingsKey.MatchAttempts];\n });\n\n return finalize({\n // TODO: should we identify UpdateLayout events as linked to this insight?\n relatedEvents: [],\n totalElapsedMs: Types.Timing.MilliSeconds(totalElapsedUs / 1000.0),\n totalMatchAttempts,\n totalMatchCount,\n topElapsedMs: sortByElapsedMs.slice(0, 3),\n topMatchAttempts: sortByMatchAttempts.slice(0, 3),\n });\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the score (1 - percentile) of `value` in a log-normal distribution
|
|
3
|
+
* specified by the `median` value, at which the score will be 0.5, and a 10th
|
|
4
|
+
* percentile value, at which the score will be 0.9. The score represents the
|
|
5
|
+
* amount of the distribution greater than `value`. All values should be in the
|
|
6
|
+
* same units (e.g. milliseconds). See
|
|
7
|
+
* https://www.desmos.com/calculator/o98tbeyt1t
|
|
8
|
+
* for an interactive view of the relationship between these parameters and the
|
|
9
|
+
* typical parameterization (location and shape) of the log-normal distribution.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getLogNormalScore({ median, p10 }: {
|
|
12
|
+
median: number;
|
|
13
|
+
p10: number;
|
|
14
|
+
}, value: number): number;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// Copyright 2024 The Chromium Authors. All rights reserved.
|
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
// Lifted from Lighthouse: https://github.com/GoogleChrome/lighthouse/blob/36cac182a6c637b1671c57326d7c0241633d0076/shared/statistics.js
|
|
5
|
+
/**
|
|
6
|
+
* @license
|
|
7
|
+
* Copyright 2017 Google LLC
|
|
8
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
9
|
+
*/
|
|
10
|
+
// The exact double values for the max and min scores possible in each range.
|
|
11
|
+
const MIN_PASSING_SCORE = 0.90000000000000002220446049250313080847263336181640625;
|
|
12
|
+
const MAX_AVERAGE_SCORE = 0.899999999999999911182158029987476766109466552734375;
|
|
13
|
+
const MIN_AVERAGE_SCORE = 0.5;
|
|
14
|
+
const MAX_FAILING_SCORE = 0.499999999999999944488848768742172978818416595458984375;
|
|
15
|
+
/**
|
|
16
|
+
* Approximates the Gauss error function, the probability that a random variable
|
|
17
|
+
* from the standard normal distribution lies within [-x, x]. Moved from
|
|
18
|
+
* traceviewer.b.math.erf, based on Abramowitz and Stegun, formula 7.1.26.
|
|
19
|
+
*/
|
|
20
|
+
function erf(x) {
|
|
21
|
+
// erf(-x) = -erf(x);
|
|
22
|
+
const sign = Math.sign(x);
|
|
23
|
+
x = Math.abs(x);
|
|
24
|
+
const a1 = 0.254829592;
|
|
25
|
+
const a2 = -0.284496736;
|
|
26
|
+
const a3 = 1.421413741;
|
|
27
|
+
const a4 = -1.453152027;
|
|
28
|
+
const a5 = 1.061405429;
|
|
29
|
+
const p = 0.3275911;
|
|
30
|
+
const t = 1 / (1 + p * x);
|
|
31
|
+
const y = t * (a1 + t * (a2 + t * (a3 + t * (a4 + t * a5))));
|
|
32
|
+
return sign * (1 - y * Math.exp(-x * x));
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Returns the score (1 - percentile) of `value` in a log-normal distribution
|
|
36
|
+
* specified by the `median` value, at which the score will be 0.5, and a 10th
|
|
37
|
+
* percentile value, at which the score will be 0.9. The score represents the
|
|
38
|
+
* amount of the distribution greater than `value`. All values should be in the
|
|
39
|
+
* same units (e.g. milliseconds). See
|
|
40
|
+
* https://www.desmos.com/calculator/o98tbeyt1t
|
|
41
|
+
* for an interactive view of the relationship between these parameters and the
|
|
42
|
+
* typical parameterization (location and shape) of the log-normal distribution.
|
|
43
|
+
*/
|
|
44
|
+
export function getLogNormalScore({ median, p10 }, value) {
|
|
45
|
+
// Required for the log-normal distribution.
|
|
46
|
+
if (median <= 0) {
|
|
47
|
+
throw new Error('median must be greater than zero');
|
|
48
|
+
}
|
|
49
|
+
if (p10 <= 0) {
|
|
50
|
+
throw new Error('p10 must be greater than zero');
|
|
51
|
+
}
|
|
52
|
+
// Not strictly required, but if p10 > median, it flips around and becomes the p90 point.
|
|
53
|
+
if (p10 >= median) {
|
|
54
|
+
throw new Error('p10 must be less than the median');
|
|
55
|
+
}
|
|
56
|
+
// Non-positive values aren't in the distribution, so always 1.
|
|
57
|
+
if (value <= 0) {
|
|
58
|
+
return 1;
|
|
59
|
+
}
|
|
60
|
+
// Closest double to `erfc-1(1/5)`.
|
|
61
|
+
const INVERSE_ERFC_ONE_FIFTH = 0.9061938024368232;
|
|
62
|
+
// Shape (σ) is `|log(p10/median) / (sqrt(2)*erfc^-1(1/5))|` and
|
|
63
|
+
// standardizedX is `1/2 erfc(log(value/median) / (sqrt(2)*σ))`, so simplify a bit.
|
|
64
|
+
const xRatio = Math.max(Number.MIN_VALUE, value / median); // value and median are > 0, so is ratio.
|
|
65
|
+
const xLogRatio = Math.log(xRatio);
|
|
66
|
+
const p10Ratio = Math.max(Number.MIN_VALUE, p10 / median); // p10 and median are > 0, so is ratio.
|
|
67
|
+
const p10LogRatio = -Math.log(p10Ratio); // negate to keep σ positive.
|
|
68
|
+
const standardizedX = xLogRatio * INVERSE_ERFC_ONE_FIFTH / p10LogRatio;
|
|
69
|
+
const complementaryPercentile = (1 - erf(standardizedX)) / 2;
|
|
70
|
+
// Clamp to avoid floating-point out-of-bounds issues and keep score in expected range.
|
|
71
|
+
let score;
|
|
72
|
+
if (value <= p10) {
|
|
73
|
+
// Passing. Clamp to [0.9, 1].
|
|
74
|
+
score = Math.max(MIN_PASSING_SCORE, Math.min(1, complementaryPercentile));
|
|
75
|
+
}
|
|
76
|
+
else if (value <= median) {
|
|
77
|
+
// Average. Clamp to [0.5, 0.9).
|
|
78
|
+
score = Math.max(MIN_AVERAGE_SCORE, Math.min(MAX_AVERAGE_SCORE, complementaryPercentile));
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
// Failing. Clamp to [0, 0.5).
|
|
82
|
+
score = Math.max(0, Math.min(MAX_FAILING_SCORE, complementaryPercentile));
|
|
83
|
+
}
|
|
84
|
+
return score;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=Statistics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Statistics.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/Statistics.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\n// Lifted from Lighthouse: https://github.com/GoogleChrome/lighthouse/blob/36cac182a6c637b1671c57326d7c0241633d0076/shared/statistics.js\n\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// The exact double values for the max and min scores possible in each range.\nconst MIN_PASSING_SCORE = 0.90000000000000002220446049250313080847263336181640625;\nconst MAX_AVERAGE_SCORE = 0.899999999999999911182158029987476766109466552734375;\nconst MIN_AVERAGE_SCORE = 0.5;\nconst MAX_FAILING_SCORE = 0.499999999999999944488848768742172978818416595458984375;\n\n/**\n * Approximates the Gauss error function, the probability that a random variable\n * from the standard normal distribution lies within [-x, x]. Moved from\n * traceviewer.b.math.erf, based on Abramowitz and Stegun, formula 7.1.26.\n */\nfunction erf(x: number): number {\n // erf(-x) = -erf(x);\n const sign = Math.sign(x);\n x = Math.abs(x);\n\n const a1 = 0.254829592;\n const a2 = -0.284496736;\n const a3 = 1.421413741;\n const a4 = -1.453152027;\n const a5 = 1.061405429;\n const p = 0.3275911;\n const t = 1 / (1 + p * x);\n const y = t * (a1 + t * (a2 + t * (a3 + t * (a4 + t * a5))));\n return sign * (1 - y * Math.exp(-x * x));\n}\n\n/**\n * Returns the score (1 - percentile) of `value` in a log-normal distribution\n * specified by the `median` value, at which the score will be 0.5, and a 10th\n * percentile value, at which the score will be 0.9. The score represents the\n * amount of the distribution greater than `value`. All values should be in the\n * same units (e.g. milliseconds). See\n * https://www.desmos.com/calculator/o98tbeyt1t\n * for an interactive view of the relationship between these parameters and the\n * typical parameterization (location and shape) of the log-normal distribution.\n */\nexport function getLogNormalScore({median, p10}: {median: number, p10: number}, value: number): number {\n // Required for the log-normal distribution.\n if (median <= 0) {\n throw new Error('median must be greater than zero');\n }\n if (p10 <= 0) {\n throw new Error('p10 must be greater than zero');\n }\n // Not strictly required, but if p10 > median, it flips around and becomes the p90 point.\n if (p10 >= median) {\n throw new Error('p10 must be less than the median');\n }\n\n // Non-positive values aren't in the distribution, so always 1.\n if (value <= 0) {\n return 1;\n }\n\n // Closest double to `erfc-1(1/5)`.\n const INVERSE_ERFC_ONE_FIFTH = 0.9061938024368232;\n\n // Shape (σ) is `|log(p10/median) / (sqrt(2)*erfc^-1(1/5))|` and\n // standardizedX is `1/2 erfc(log(value/median) / (sqrt(2)*σ))`, so simplify a bit.\n const xRatio = Math.max(Number.MIN_VALUE, value / median); // value and median are > 0, so is ratio.\n const xLogRatio = Math.log(xRatio);\n const p10Ratio = Math.max(Number.MIN_VALUE, p10 / median); // p10 and median are > 0, so is ratio.\n const p10LogRatio = -Math.log(p10Ratio); // negate to keep σ positive.\n const standardizedX = xLogRatio * INVERSE_ERFC_ONE_FIFTH / p10LogRatio;\n const complementaryPercentile = (1 - erf(standardizedX)) / 2;\n\n // Clamp to avoid floating-point out-of-bounds issues and keep score in expected range.\n let score;\n if (value <= p10) {\n // Passing. Clamp to [0.9, 1].\n score = Math.max(MIN_PASSING_SCORE, Math.min(1, complementaryPercentile));\n } else if (value <= median) {\n // Average. Clamp to [0.5, 0.9).\n score = Math.max(MIN_AVERAGE_SCORE, Math.min(MAX_AVERAGE_SCORE, complementaryPercentile));\n } else {\n // Failing. Clamp to [0, 0.5).\n score = Math.max(0, Math.min(MAX_FAILING_SCORE, complementaryPercentile));\n }\n return score;\n}\n"]}
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import * as Extras from '../extras/extras.js';
|
|
2
2
|
import type * as Types from '../types/types.js';
|
|
3
3
|
import { type InsightModel, type InsightSetContext, type RequiredData } from './types.js';
|
|
4
|
+
export declare const UIStrings: {
|
|
5
|
+
/** Title of an insight that provides details about the code on a web page that the user doesn't control (referred to as "third-party code"). */
|
|
6
|
+
title: string;
|
|
7
|
+
/**
|
|
8
|
+
* @description Description of a DevTools insight that identifies the code on the page that the user doesn't control.
|
|
9
|
+
* This is displayed after a user expands the section to see more. No character length limits.
|
|
10
|
+
*/
|
|
11
|
+
description: string;
|
|
12
|
+
};
|
|
4
13
|
export declare function deps(): ['Meta', 'NetworkRequests', 'Renderer', 'ImagePainting'];
|
|
5
14
|
export type ThirdPartiesInsightModel = InsightModel<{
|
|
6
15
|
entityByRequest: Map<Types.Events.SyntheticNetworkRequest, Extras.ThirdParties.Entity>;
|
|
7
|
-
requestsByEntity: Map<Extras.ThirdParties.Entity, Types.Events.
|
|
8
|
-
|
|
16
|
+
requestsByEntity: Map<Extras.ThirdParties.Entity, Types.Events.Event[]>;
|
|
17
|
+
summaryByEvent: Map<Types.Events.Event, Extras.ThirdParties.Summary>;
|
|
9
18
|
summaryByEntity: Map<Extras.ThirdParties.Entity, Extras.ThirdParties.Summary>;
|
|
10
19
|
/** The entity for this navigation's URL. Any other entity is from a third party. */
|
|
11
20
|
firstPartyEntity?: Extras.ThirdParties.Entity;
|
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
// import * as i18n from '../../../core/i18n/i18n.js';
|
|
5
5
|
import * as ThirdPartyWeb from '../../../third_party/third-party-web/third-party-web.js';
|
|
6
6
|
import * as Extras from '../extras/extras.js';
|
|
7
|
+
import * as Handlers from '../handlers/handlers.js';
|
|
7
8
|
import * as Helpers from '../helpers/helpers.js';
|
|
8
9
|
import { InsightCategory } from './types.js';
|
|
9
|
-
const UIStrings = {
|
|
10
|
+
export const UIStrings = {
|
|
10
11
|
/** Title of an insight that provides details about the code on a web page that the user doesn't control (referred to as "third-party code"). */
|
|
11
12
|
title: 'Third parties',
|
|
12
13
|
/**
|
|
@@ -23,7 +24,7 @@ export function deps() {
|
|
|
23
24
|
}
|
|
24
25
|
function getRelatedEvents(summaries, firstPartyEntity) {
|
|
25
26
|
const events = [];
|
|
26
|
-
for (const [entity, requests] of summaries.
|
|
27
|
+
for (const [entity, requests] of summaries.eventsByEntity.entries()) {
|
|
27
28
|
if (entity !== firstPartyEntity) {
|
|
28
29
|
events.push(...requests);
|
|
29
30
|
}
|
|
@@ -52,12 +53,12 @@ export function generateInsight(parsedTrace, context) {
|
|
|
52
53
|
const { entityByRequest, madeUpEntityCache, summaries } = Extras.ThirdParties.getSummariesAndEntitiesForTraceBounds(parsedTrace, context.bounds, networkRequests);
|
|
53
54
|
const firstPartyUrl = context.navigation?.args.data?.documentLoaderURL ?? parsedTrace.Meta.mainFrameURL;
|
|
54
55
|
const firstPartyEntity = ThirdPartyWeb.ThirdPartyWeb.getEntity(firstPartyUrl) ||
|
|
55
|
-
|
|
56
|
+
Handlers.Helpers.makeUpEntity(madeUpEntityCache, firstPartyUrl);
|
|
56
57
|
return finalize({
|
|
57
58
|
relatedEvents: getRelatedEvents(summaries, firstPartyEntity),
|
|
58
59
|
entityByRequest,
|
|
59
|
-
requestsByEntity: summaries.
|
|
60
|
-
|
|
60
|
+
requestsByEntity: summaries.eventsByEntity,
|
|
61
|
+
summaryByEvent: summaries.byEvent,
|
|
61
62
|
summaryByEntity: summaries.byEntity,
|
|
62
63
|
firstPartyEntity,
|
|
63
64
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThirdParties.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/ThirdParties.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,IAAI,MAAM,4BAA4B,CAAC;AACnD,OAAO,KAAK,aAAa,MAAM,yDAAyD,CAAC;AACzF,OAAO,KAAK,MAAM,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"ThirdParties.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/ThirdParties.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 i18n from '../../../core/i18n/i18n.js';\nimport * as ThirdPartyWeb from '../../../third_party/third-party-web/third-party-web.js';\nimport * as Extras from '../extras/extras.js';\nimport * as Handlers from '../handlers/handlers.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport type * as Types from '../types/types.js';\n\nimport {InsightCategory, type InsightModel, type InsightSetContext, type RequiredData} from './types.js';\n\nexport const UIStrings = {\n /** Title of an insight that provides details about the code on a web page that the user doesn't control (referred to as \"third-party code\"). */\n title: 'Third parties',\n /**\n * @description Description of a DevTools insight that identifies the code on the page that the user doesn't control.\n * This is displayed after a user expands the section to see more. No character length limits.\n */\n description: 'Third party code can significantly impact load performance. ' +\n '[Reduce and defer loading of third party code](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/) to prioritize your page\\'s content.',\n};\n\nconst str_ = i18n.i18n.registerUIStrings('models/trace/insights/ThirdParties.ts', UIStrings);\nconst i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);\n\nexport function deps(): ['Meta', 'NetworkRequests', 'Renderer', 'ImagePainting'] {\n return ['Meta', 'NetworkRequests', 'Renderer', 'ImagePainting'];\n}\n\nexport type ThirdPartiesInsightModel = InsightModel<{\n entityByRequest: Map<Types.Events.SyntheticNetworkRequest, Extras.ThirdParties.Entity>,\n requestsByEntity: Map<Extras.ThirdParties.Entity, Types.Events.Event[]>,\n summaryByEvent: Map<Types.Events.Event, Extras.ThirdParties.Summary>,\n summaryByEntity: Map<Extras.ThirdParties.Entity, Extras.ThirdParties.Summary>,\n /** The entity for this navigation's URL. Any other entity is from a third party. */\n firstPartyEntity?: Extras.ThirdParties.Entity,\n}>;\n\nfunction getRelatedEvents(\n summaries: Extras.ThirdParties.SummaryMaps,\n firstPartyEntity: Extras.ThirdParties.Entity|undefined): Types.Events.Event[] {\n const events = [];\n\n for (const [entity, requests] of summaries.eventsByEntity.entries()) {\n if (entity !== firstPartyEntity) {\n events.push(...requests);\n }\n }\n\n return events;\n}\n\nfunction finalize(partialModel: Omit<ThirdPartiesInsightModel, 'title'|'description'|'category'|'shouldShow'>):\n ThirdPartiesInsightModel {\n return {\n title: i18nString(UIStrings.title),\n description: i18nString(UIStrings.description),\n category: InsightCategory.ALL,\n shouldShow:\n Boolean([...partialModel.summaryByEntity.entries()].find(kv => kv[0] !== partialModel.firstPartyEntity)),\n ...partialModel,\n };\n}\n\nexport function generateInsight(\n parsedTrace: RequiredData<typeof deps>, context: InsightSetContext): ThirdPartiesInsightModel {\n const networkRequests = parsedTrace.NetworkRequests.byTime.filter(event => {\n if (!context.navigation) {\n return false;\n }\n\n if (event.args.data.frame !== context.frameId) {\n return false;\n }\n\n return Helpers.Timing.eventIsInBounds(event, context.bounds);\n });\n\n const {entityByRequest, madeUpEntityCache, summaries} = Extras.ThirdParties.getSummariesAndEntitiesForTraceBounds(\n parsedTrace as Handlers.Types.ParsedTrace, context.bounds, networkRequests);\n\n const firstPartyUrl = context.navigation?.args.data?.documentLoaderURL ?? parsedTrace.Meta.mainFrameURL;\n const firstPartyEntity = ThirdPartyWeb.ThirdPartyWeb.getEntity(firstPartyUrl) ||\n Handlers.Helpers.makeUpEntity(madeUpEntityCache, firstPartyUrl);\n\n return finalize({\n relatedEvents: getRelatedEvents(summaries, firstPartyEntity),\n entityByRequest,\n requestsByEntity: summaries.eventsByEntity,\n summaryByEvent: summaries.byEvent,\n summaryByEntity: summaries.byEntity,\n firstPartyEntity,\n });\n}\n"]}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import type * as Types from '../types/types.js';
|
|
2
2
|
import { type InsightModel, type InsightSetContext, type RequiredData } from './types.js';
|
|
3
|
+
export declare const UIStrings: {
|
|
4
|
+
/** Title of an insight that provides details about if the page's viewport is optimized for mobile viewing. */
|
|
5
|
+
title: string;
|
|
6
|
+
/**
|
|
7
|
+
* @description Text to tell the user how a viewport meta element can improve performance. \xa0 is a non-breaking space
|
|
8
|
+
*/
|
|
9
|
+
description: string;
|
|
10
|
+
};
|
|
3
11
|
export declare function deps(): ['Meta', 'UserInteractions'];
|
|
4
12
|
export type ViewportInsightModel = InsightModel<{
|
|
5
13
|
mobileOptimized: boolean | null;
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
// import * as i18n from '../../../core/i18n/i18n.js';
|
|
5
5
|
import * as Helpers from '../helpers/helpers.js';
|
|
6
6
|
import { InsightCategory, InsightWarning, } from './types.js';
|
|
7
|
-
const UIStrings = {
|
|
7
|
+
export const UIStrings = {
|
|
8
8
|
/** Title of an insight that provides details about if the page's viewport is optimized for mobile viewing. */
|
|
9
|
-
title: '
|
|
9
|
+
title: 'Optimize viewport for mobile',
|
|
10
10
|
/**
|
|
11
11
|
* @description Text to tell the user how a viewport meta element can improve performance. \xa0 is a non-breaking space
|
|
12
12
|
*/
|
|
13
|
-
description: '
|
|
13
|
+
description: 'Tap interactions may be [delayed by up to 300\xA0ms](https://developer.chrome.com/blog/300ms-tap-delay-gone-away/) if the viewport is not optimized for mobile.',
|
|
14
14
|
};
|
|
15
15
|
// const str_ = i18n.i18n.registerUIStrings('models/trace/insights/Viewport.ts', UIStrings);
|
|
16
16
|
const i18nString = string => string; // i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Viewport.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/Viewport.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,IAAI,MAAM,4BAA4B,CAAC;AACnD,OAAO,KAAK,OAAO,MAAM,uBAAuB,CAAC;AAGjD,OAAO,EACL,eAAe,EAGf,cAAc,GAEf,MAAM,YAAY,CAAC;AAEpB,MAAM,SAAS,GAAG;
|
|
1
|
+
{"version":3,"file":"Viewport.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/Viewport.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,IAAI,MAAM,4BAA4B,CAAC;AACnD,OAAO,KAAK,OAAO,MAAM,uBAAuB,CAAC;AAGjD,OAAO,EACL,eAAe,EAGf,cAAc,GAEf,MAAM,YAAY,CAAC;AAEpB,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,8GAA8G;IAC9G,KAAK,EAAE,8BAA8B;IACrC;;OAEG;IACH,WAAW,EACP,iKAAiK;CACtK,CAAC;AAEF,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,mCAAmC,EAAE,SAAS,CAAC,CAAC;AACzF,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAEtE,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;AACtC,CAAC;AAOD,SAAS,QAAQ,CAAC,YAAuF;IAEvG,OAAO;QACL,KAAK,EAAE,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC;QAClC,WAAW,EAAE,UAAU,CAAC,SAAS,CAAC,WAAW,CAAC;QAC9C,QAAQ,EAAE,eAAe,CAAC,GAAG;QAC7B,UAAU,EAAE,YAAY,CAAC,eAAe,KAAK,KAAK;QAClD,GAAG,YAAY;KAChB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAC3B,WAAsC,EAAE,OAA0B;IACpE,MAAM,gBAAgB,GAAG,WAAW,CAAC,gBAAgB,CAAC,gCAAgC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;QACpG,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC;YACzC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC;QAC7B,uCAAuC;QACvC,OAAO,QAAQ,CAAC;YACd,eAAe,EAAE,IAAI;YACrB,QAAQ,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC;SACrC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,aAAa,GAAG,WAAW,CAAC,gBAAgB,CAAC,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;QACtF,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC;YAC9C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,wDAAwD;IACxD,KAAK,MAAM,KAAK,IAAI,gBAAgB,EAAE,CAAC;QACrC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YACpC,OAAO,QAAQ,CAAC;gBACd,eAAe,EAAE,KAAK;gBACtB,aAAa;gBACb,aAAa,EAAE,EAAC,GAAG,EAAE,GAAgC,EAAC;aACvD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;QACd,eAAe,EAAE,IAAI;QACrB,aAAa;KACd,CAAC,CAAC;AACL,CAAC","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 i18n from '../../../core/i18n/i18n.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport type * as Types from '../types/types.js';\n\nimport {\n InsightCategory,\n type InsightModel,\n type InsightSetContext,\n InsightWarning,\n type RequiredData,\n} from './types.js';\n\nexport const UIStrings = {\n /** Title of an insight that provides details about if the page's viewport is optimized for mobile viewing. */\n title: 'Optimize viewport for mobile',\n /**\n * @description Text to tell the user how a viewport meta element can improve performance. \\xa0 is a non-breaking space\n */\n description:\n 'Tap interactions may be [delayed by up to 300\\xA0ms](https://developer.chrome.com/blog/300ms-tap-delay-gone-away/) if the viewport is not optimized for mobile.',\n};\n\nconst str_ = i18n.i18n.registerUIStrings('models/trace/insights/Viewport.ts', UIStrings);\nconst i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);\n\nexport function deps(): ['Meta', 'UserInteractions'] {\n return ['Meta', 'UserInteractions'];\n}\n\nexport type ViewportInsightModel = InsightModel<{\n mobileOptimized: boolean | null,\n viewportEvent?: Types.Events.ParseMetaViewport,\n}>;\n\nfunction finalize(partialModel: Omit<ViewportInsightModel, 'title'|'description'|'category'|'shouldShow'>):\n ViewportInsightModel {\n return {\n title: i18nString(UIStrings.title),\n description: i18nString(UIStrings.description),\n category: InsightCategory.INP,\n shouldShow: partialModel.mobileOptimized === false,\n ...partialModel,\n };\n}\n\nexport function generateInsight(\n parsedTrace: RequiredData<typeof deps>, context: InsightSetContext): ViewportInsightModel {\n const compositorEvents = parsedTrace.UserInteractions.beginCommitCompositorFrameEvents.filter(event => {\n if (event.args.frame !== context.frameId) {\n return false;\n }\n\n return Helpers.Timing.eventIsInBounds(event, context.bounds);\n });\n\n if (!compositorEvents.length) {\n // Trace doesn't have the data we need.\n return finalize({\n mobileOptimized: null,\n warnings: [InsightWarning.NO_LAYOUT],\n });\n }\n\n const viewportEvent = parsedTrace.UserInteractions.parseMetaViewportEvents.find(event => {\n if (event.args.data.frame !== context.frameId) {\n return false;\n }\n\n return Helpers.Timing.eventIsInBounds(event, context.bounds);\n });\n\n // Returns true only if all events are mobile optimized.\n for (const event of compositorEvents) {\n if (!event.args.is_mobile_optimized) {\n return finalize({\n mobileOptimized: false,\n viewportEvent,\n metricSavings: {INP: 300 as Types.Timing.MilliSeconds},\n });\n }\n }\n\n return finalize({\n mobileOptimized: true,\n viewportEvent,\n });\n}\n"]}
|
|
@@ -32,7 +32,8 @@
|
|
|
32
32
|
"../../../../../../../front_end/models/trace/insights/insights.ts",
|
|
33
33
|
"../../../../../../../front_end/legacy/legacy-defs.d.ts",
|
|
34
34
|
"../../../../../../../front_end/global_typings/global_defs.d.ts",
|
|
35
|
-
"../../../../../../../node_modules/@types/filesystem/index.d.ts"
|
|
35
|
+
"../../../../../../../node_modules/@types/filesystem/index.d.ts",
|
|
36
|
+
"../../../../../../../node_modules/@types/wicg-task-scheduling/index.d.ts"
|
|
36
37
|
],
|
|
37
38
|
"references": [
|
|
38
39
|
{
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"files": [
|
|
32
32
|
"../../../../../../../front_end/models/trace/insights/CLSCulprits.ts",
|
|
33
33
|
"../../../../../../../front_end/models/trace/insights/Common.ts",
|
|
34
|
+
"../../../../../../../front_end/models/trace/insights/DOMSize.ts",
|
|
34
35
|
"../../../../../../../front_end/models/trace/insights/DocumentLatency.ts",
|
|
35
36
|
"../../../../../../../front_end/models/trace/insights/FontDisplay.ts",
|
|
36
37
|
"../../../../../../../front_end/models/trace/insights/ImageDelivery.ts",
|
|
@@ -40,12 +41,14 @@
|
|
|
40
41
|
"../../../../../../../front_end/models/trace/insights/Models.ts",
|
|
41
42
|
"../../../../../../../front_end/models/trace/insights/RenderBlocking.ts",
|
|
42
43
|
"../../../../../../../front_end/models/trace/insights/SlowCSSSelector.ts",
|
|
44
|
+
"../../../../../../../front_end/models/trace/insights/Statistics.ts",
|
|
43
45
|
"../../../../../../../front_end/models/trace/insights/ThirdParties.ts",
|
|
44
46
|
"../../../../../../../front_end/models/trace/insights/Viewport.ts",
|
|
45
47
|
"../../../../../../../front_end/models/trace/insights/types.ts",
|
|
46
48
|
"../../../../../../../front_end/legacy/legacy-defs.d.ts",
|
|
47
49
|
"../../../../../../../front_end/global_typings/global_defs.d.ts",
|
|
48
|
-
"../../../../../../../node_modules/@types/filesystem/index.d.ts"
|
|
50
|
+
"../../../../../../../node_modules/@types/filesystem/index.d.ts",
|
|
51
|
+
"../../../../../../../node_modules/@types/wicg-task-scheduling/index.d.ts"
|
|
49
52
|
],
|
|
50
53
|
"references": [
|
|
51
54
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"insights.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/insights.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC","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\nexport * as Common from './Common.js';\nexport * as Models from './Models.js';\nexport * as Types from './types.js';\n"]}
|
|
1
|
+
{"version":3,"file":"insights.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/insights.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC","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\nexport * as Common from './Common.js';\nexport * as Models from './Models.js';\nexport * as Statistics from './Statistics.js';\nexport * as Types from './types.js';\n"]}
|
|
@@ -44,13 +44,14 @@ export declare enum InsightCategory {
|
|
|
44
44
|
LCP = "LCP",
|
|
45
45
|
CLS = "CLS"
|
|
46
46
|
}
|
|
47
|
+
export type RelatedEventsMap = Map<Types.Events.Event, string[]>;
|
|
47
48
|
export type InsightModel<R extends Record<string, unknown>> = R & {
|
|
48
49
|
title: string;
|
|
49
50
|
description: string;
|
|
50
51
|
category: InsightCategory;
|
|
51
52
|
/** True if there is anything of interest to display to the user. */
|
|
52
53
|
shouldShow: boolean;
|
|
53
|
-
relatedEvents?: Types.Events.Event[];
|
|
54
|
+
relatedEvents?: RelatedEventsMap | Types.Events.Event[];
|
|
54
55
|
warnings?: InsightWarning[];
|
|
55
56
|
metricSavings?: MetricSavings;
|
|
56
57
|
};
|
|
@@ -59,7 +60,7 @@ export type InsightModel<R extends Record<string, unknown>> = R & {
|
|
|
59
60
|
* this could instead represent the duration from the beginning of the trace up to the first recorded
|
|
60
61
|
* navigation (or the end of the trace).
|
|
61
62
|
*/
|
|
62
|
-
export
|
|
63
|
+
export interface InsightSet {
|
|
63
64
|
/** If for a navigation, this is the navigationId. Else it is Trace.Types.Events.NO_NAVIGATION. */
|
|
64
65
|
id: Types.Events.NavigationId;
|
|
65
66
|
/** The URL to show in the accordion list. */
|
|
@@ -68,7 +69,7 @@ export type InsightSet = {
|
|
|
68
69
|
bounds: Types.Timing.TraceWindowMicroSeconds;
|
|
69
70
|
model: InsightModels;
|
|
70
71
|
navigation?: Types.Events.NavigationStart;
|
|
71
|
-
}
|
|
72
|
+
}
|
|
72
73
|
/**
|
|
73
74
|
* Contains insights for a specific insight set.
|
|
74
75
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/types.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAoC7B,MAAM,CAAN,IAAY,cAMX;AAND,WAAY,cAAc;IACxB,iCAAe,CAAA;IACf,mCAAiB,CAAA;IACjB,uEAAuE;IACvE,6DAA2C,CAAA;IAC3C,yCAAuB,CAAA;AACzB,CAAC,EANW,cAAc,KAAd,cAAc,QAMzB;AAYD,MAAM,CAAN,IAAY,eAKX;AALD,WAAY,eAAe;IACzB,8BAAW,CAAA;IACX,8BAAW,CAAA;IACX,8BAAW,CAAA;IACX,8BAAW,CAAA;AACb,CAAC,EALW,eAAe,KAAf,eAAe,QAK1B","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 type * as Common from '../../../core/common/common.js';\nimport type * as Handlers from '../handlers/handlers.js';\nimport type * as Lantern from '../lantern/lantern.js';\nimport type * as Types from '../types/types.js';\n\nimport type * as Models from './Models.js';\n\n/**\n * Context for the portion of the trace an insight should look at.\n */\nexport type InsightSetContext = InsightSetContextWithoutNavigation|InsightSetContextWithNavigation;\n\nexport interface InsightSetContextWithoutNavigation {\n bounds: Types.Timing.TraceWindowMicroSeconds;\n frameId: string;\n navigation?: never;\n}\n\nexport interface InsightSetContextWithNavigation {\n bounds: Types.Timing.TraceWindowMicroSeconds;\n frameId: string;\n navigation: Types.Events.NavigationStart;\n navigationId: string;\n lantern?: LanternContext;\n}\n\nexport interface LanternContext {\n graph: Lantern.Graph.Node<Types.Events.SyntheticNetworkRequest>;\n simulator: Lantern.Simulation.Simulator<Types.Events.SyntheticNetworkRequest>;\n metrics: Record<string, Lantern.Metrics.MetricResult>;\n}\n\nexport type InsightModelsType = typeof Models;\n\nexport enum InsightWarning {\n NO_FP = 'NO_FP',\n NO_LCP = 'NO_LCP',\n // No network request could be identified as the primary HTML document.\n NO_DOCUMENT_REQUEST = 'NO_DOCUMENT_REQUEST',\n NO_LAYOUT = 'NO_LAYOUT',\n}\n\nexport interface MetricSavings {\n /* eslint-disable @typescript-eslint/naming-convention */\n FCP?: Types.Timing.MilliSeconds;\n LCP?: Types.Timing.MilliSeconds;\n TBT?: Types.Timing.MilliSeconds;\n CLS?: number;\n INP?: Types.Timing.MilliSeconds;\n /* eslint-enable @typescript-eslint/naming-convention */\n}\n\nexport enum InsightCategory {\n ALL = 'All',\n INP = 'INP',\n LCP = 'LCP',\n CLS = 'CLS',\n}\n\nexport type InsightModel<R extends Record<string, unknown>> = R&{\n title: Common.UIString.LocalizedString,\n description: Common.UIString.LocalizedString,\n category: InsightCategory,\n /** True if there is anything of interest to display to the user. */\n shouldShow: boolean,\n relatedEvents?: Types.Events.Event[],\n warnings?: InsightWarning[],\n metricSavings?: MetricSavings,\n};\n\n/**\n * Contains insights for a specific navigation. If a trace began after a navigation already started,\n * this could instead represent the duration from the beginning of the trace up to the first recorded\n * navigation (or the end of the trace).\n */\nexport
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/types.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAoC7B,MAAM,CAAN,IAAY,cAMX;AAND,WAAY,cAAc;IACxB,iCAAe,CAAA;IACf,mCAAiB,CAAA;IACjB,uEAAuE;IACvE,6DAA2C,CAAA;IAC3C,yCAAuB,CAAA;AACzB,CAAC,EANW,cAAc,KAAd,cAAc,QAMzB;AAYD,MAAM,CAAN,IAAY,eAKX;AALD,WAAY,eAAe;IACzB,8BAAW,CAAA;IACX,8BAAW,CAAA;IACX,8BAAW,CAAA;IACX,8BAAW,CAAA;AACb,CAAC,EALW,eAAe,KAAf,eAAe,QAK1B","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 type * as Common from '../../../core/common/common.js';\nimport type * as Handlers from '../handlers/handlers.js';\nimport type * as Lantern from '../lantern/lantern.js';\nimport type * as Types from '../types/types.js';\n\nimport type * as Models from './Models.js';\n\n/**\n * Context for the portion of the trace an insight should look at.\n */\nexport type InsightSetContext = InsightSetContextWithoutNavigation|InsightSetContextWithNavigation;\n\nexport interface InsightSetContextWithoutNavigation {\n bounds: Types.Timing.TraceWindowMicroSeconds;\n frameId: string;\n navigation?: never;\n}\n\nexport interface InsightSetContextWithNavigation {\n bounds: Types.Timing.TraceWindowMicroSeconds;\n frameId: string;\n navigation: Types.Events.NavigationStart;\n navigationId: string;\n lantern?: LanternContext;\n}\n\nexport interface LanternContext {\n graph: Lantern.Graph.Node<Types.Events.SyntheticNetworkRequest>;\n simulator: Lantern.Simulation.Simulator<Types.Events.SyntheticNetworkRequest>;\n metrics: Record<string, Lantern.Metrics.MetricResult>;\n}\n\nexport type InsightModelsType = typeof Models;\n\nexport enum InsightWarning {\n NO_FP = 'NO_FP',\n NO_LCP = 'NO_LCP',\n // No network request could be identified as the primary HTML document.\n NO_DOCUMENT_REQUEST = 'NO_DOCUMENT_REQUEST',\n NO_LAYOUT = 'NO_LAYOUT',\n}\n\nexport interface MetricSavings {\n /* eslint-disable @typescript-eslint/naming-convention */\n FCP?: Types.Timing.MilliSeconds;\n LCP?: Types.Timing.MilliSeconds;\n TBT?: Types.Timing.MilliSeconds;\n CLS?: number;\n INP?: Types.Timing.MilliSeconds;\n /* eslint-enable @typescript-eslint/naming-convention */\n}\n\nexport enum InsightCategory {\n ALL = 'All',\n INP = 'INP',\n LCP = 'LCP',\n CLS = 'CLS',\n}\n\nexport type RelatedEventsMap = Map<Types.Events.Event, string[]>;\n\nexport type InsightModel<R extends Record<string, unknown>> = R&{\n title: Common.UIString.LocalizedString,\n description: Common.UIString.LocalizedString,\n category: InsightCategory,\n /** True if there is anything of interest to display to the user. */\n shouldShow: boolean,\n relatedEvents?: RelatedEventsMap | Types.Events.Event[],\n warnings?: InsightWarning[],\n metricSavings?: MetricSavings,\n};\n\n/**\n * Contains insights for a specific navigation. If a trace began after a navigation already started,\n * this could instead represent the duration from the beginning of the trace up to the first recorded\n * navigation (or the end of the trace).\n */\nexport interface InsightSet {\n /** If for a navigation, this is the navigationId. Else it is Trace.Types.Events.NO_NAVIGATION. */\n id: Types.Events.NavigationId;\n /** The URL to show in the accordion list. */\n url: URL;\n frameId: string;\n bounds: Types.Timing.TraceWindowMicroSeconds;\n model: InsightModels;\n navigation?: Types.Events.NavigationStart;\n}\n\n/**\n * Contains insights for a specific insight set.\n */\nexport type InsightModels = {\n [I in keyof InsightModelsType]: ReturnType<InsightModelsType[I]['generateInsight']>;\n};\n\n/**\n * Contains insights for the entire trace. Insights are mostly grouped by `navigationId`, with one exception:\n *\n * If the analyzed trace started after the navigation, and has meaningful work with that span, there is no\n * navigation to map it to. In this case `Types.Events.NO_NAVIGATION` is used for the key.\n */\nexport type TraceInsightSets = Map<Types.Events.NavigationId, InsightSet>;\n\n/**\n * Represents the narrow set of dependencies defined by an insight's `deps()` function. `Meta` is always included regardless of `deps()`.\n */\nexport type RequiredData<D extends() => Array<keyof typeof Handlers.ModelHandlers>> =\n Handlers.Types.EnabledHandlerDataWithMeta<Pick<typeof Handlers.ModelHandlers, ReturnType<D>[number]>>;\n"]}
|
|
@@ -24,11 +24,11 @@ interface RTTEstimateOptions {
|
|
|
24
24
|
/** Useful for testing to isolate the different methods of estimation. */
|
|
25
25
|
useHeadersEndEstimates?: boolean;
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
interface RequestInfo {
|
|
28
28
|
request: Lantern.NetworkRequest;
|
|
29
29
|
timing: Lantern.ResourceTiming;
|
|
30
30
|
connectionReused?: boolean;
|
|
31
|
-
}
|
|
31
|
+
}
|
|
32
32
|
declare class NetworkAnalyzer {
|
|
33
33
|
static get summary(): string;
|
|
34
34
|
static groupByOrigin(records: Lantern.NetworkRequest[]): Map<string, Lantern.NetworkRequest[]>;
|
|
@@ -31,7 +31,7 @@ class UrlUtils {
|
|
|
31
31
|
urlb.hash = '';
|
|
32
32
|
return urla.href === urlb.href;
|
|
33
33
|
}
|
|
34
|
-
catch
|
|
34
|
+
catch {
|
|
35
35
|
return false;
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -310,7 +310,6 @@ class NetworkAnalyzer {
|
|
|
310
310
|
const estimatesByOrigin = new Map();
|
|
311
311
|
for (const [origin, originRequests] of groupedByOrigin.entries()) {
|
|
312
312
|
const originEstimates = [];
|
|
313
|
-
// eslint-disable-next-line no-inner-declarations
|
|
314
313
|
function collectEstimates(estimator, multiplier = 1) {
|
|
315
314
|
for (const request of originRequests) {
|
|
316
315
|
const timing = request.timing;
|
|
@@ -470,7 +469,7 @@ class NetworkAnalyzer {
|
|
|
470
469
|
}
|
|
471
470
|
static findLastDocumentForUrl(records, resourceUrl) {
|
|
472
471
|
// equalWithExcludedFragments is expensive, so check that the resourceUrl starts with the request url first
|
|
473
|
-
const matchingRequests = records.filter(request => request.resourceType === 'Document' &&
|
|
472
|
+
const matchingRequests = records.filter(request => request.resourceType === 'Document' && !request.failed &&
|
|
474
473
|
// Note: `request.url` should never have a fragment, else this optimization gives wrong results.
|
|
475
474
|
resourceUrl.startsWith(request.url) && UrlUtils.equalWithExcludedFragments(request.url, resourceUrl));
|
|
476
475
|
return matchingRequests[matchingRequests.length - 1];
|