@paulirish/trace_engine 0.0.32 → 0.0.33
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/README.md +6 -10
- package/analyze-trace.mjs +9 -10
- package/core/platform/ArrayUtilities.js +1 -0
- package/core/platform/ArrayUtilities.js.map +1 -1
- package/core/platform/DevToolsPath.d.ts +1 -1
- package/core/platform/DevToolsPath.js.map +1 -1
- package/core/platform/MimeType.js +4 -2
- package/core/platform/MimeType.js.map +1 -1
- package/core/platform/NumberUtilities.js +8 -0
- package/core/platform/NumberUtilities.js.map +1 -1
- package/core/platform/ServerTiming.d.ts +31 -0
- package/core/platform/ServerTiming.js +212 -0
- package/core/platform/ServerTiming.js.map +1 -0
- package/core/platform/Timing.d.ts +1 -1
- package/core/platform/Timing.js.map +1 -1
- package/core/platform/TypescriptUtilities.d.ts +3 -0
- package/core/platform/TypescriptUtilities.js.map +1 -1
- package/core/platform/UIString.d.ts +1 -1
- package/core/platform/UIString.js.map +1 -1
- package/core/platform/UserVisibleError.d.ts +1 -1
- package/core/platform/UserVisibleError.js.map +1 -1
- package/core/platform/platform-tsconfig.json +1 -1
- package/core/platform/platform.d.ts +2 -2
- package/core/platform/platform.js +2 -2
- package/core/platform/platform.js.map +1 -1
- package/generated/protocol.d.ts +258 -14
- package/models/trace/LanternComputationData.d.ts +4 -4
- package/models/trace/LanternComputationData.js +22 -23
- package/models/trace/LanternComputationData.js.map +1 -1
- package/models/trace/ModelImpl.d.ts +11 -12
- package/models/trace/ModelImpl.js +22 -33
- package/models/trace/ModelImpl.js.map +1 -1
- package/models/trace/Processor.d.ts +21 -12
- package/models/trace/Processor.js +148 -67
- package/models/trace/Processor.js.map +1 -1
- package/models/trace/TracingManager.js.map +1 -1
- package/models/trace/extras/FetchNodes.d.ts +8 -8
- package/models/trace/extras/FetchNodes.js +16 -11
- package/models/trace/extras/FetchNodes.js.map +1 -1
- package/models/trace/extras/FilmStrip.d.ts +2 -2
- package/models/trace/extras/FilmStrip.js +8 -8
- package/models/trace/extras/FilmStrip.js.map +1 -1
- package/models/trace/extras/MainThreadActivity.d.ts +1 -1
- package/models/trace/extras/MainThreadActivity.js +1 -1
- package/models/trace/extras/MainThreadActivity.js.map +1 -1
- package/models/trace/extras/Metadata.js +2 -2
- package/models/trace/extras/Metadata.js.map +1 -1
- package/models/trace/extras/URLForEntry.d.ts +9 -1
- package/models/trace/extras/URLForEntry.js +18 -10
- package/models/trace/extras/URLForEntry.js.map +1 -1
- package/models/trace/extras/extras.js +1 -1
- package/models/trace/handlers/AnimationHandler.d.ts +2 -2
- package/models/trace/handlers/AnimationHandler.js +1 -1
- package/models/trace/handlers/AnimationHandler.js.map +1 -1
- package/models/trace/handlers/AuctionWorkletsHandler.d.ts +2 -2
- package/models/trace/handlers/AuctionWorkletsHandler.js +11 -11
- package/models/trace/handlers/AuctionWorkletsHandler.js.map +1 -1
- package/models/trace/handlers/ExtensionTraceDataHandler.d.ts +6 -6
- package/models/trace/handlers/ExtensionTraceDataHandler.js +12 -8
- package/models/trace/handlers/ExtensionTraceDataHandler.js.map +1 -1
- package/models/trace/handlers/FramesHandler.d.ts +24 -19
- package/models/trace/handlers/FramesHandler.js +46 -25
- package/models/trace/handlers/FramesHandler.js.map +1 -1
- package/models/trace/handlers/GPUHandler.d.ts +4 -4
- package/models/trace/handlers/GPUHandler.js +3 -3
- package/models/trace/handlers/GPUHandler.js.map +1 -1
- package/models/trace/handlers/ImagePaintingHandler.d.ts +3 -3
- package/models/trace/handlers/ImagePaintingHandler.js +6 -8
- package/models/trace/handlers/ImagePaintingHandler.js.map +1 -1
- package/models/trace/handlers/InitiatorsHandler.d.ts +3 -3
- package/models/trace/handlers/InitiatorsHandler.js +14 -14
- package/models/trace/handlers/InitiatorsHandler.js.map +1 -1
- package/models/trace/handlers/InvalidationsHandler.d.ts +4 -2
- package/models/trace/handlers/InvalidationsHandler.js +29 -11
- package/models/trace/handlers/InvalidationsHandler.js.map +1 -1
- package/models/trace/handlers/LargestImagePaintHandler.d.ts +2 -2
- package/models/trace/handlers/LargestImagePaintHandler.js +1 -1
- package/models/trace/handlers/LargestImagePaintHandler.js.map +1 -1
- package/models/trace/handlers/LargestTextPaintHandler.d.ts +2 -2
- package/models/trace/handlers/LargestTextPaintHandler.js +1 -1
- package/models/trace/handlers/LargestTextPaintHandler.js.map +1 -1
- package/models/trace/handlers/LayerTreeHandler.d.ts +6 -6
- package/models/trace/handlers/LayerTreeHandler.js +6 -6
- package/models/trace/handlers/LayerTreeHandler.js.map +1 -1
- package/models/trace/handlers/LayoutShiftsHandler.d.ts +12 -20
- package/models/trace/handlers/LayoutShiftsHandler.js +73 -12
- package/models/trace/handlers/LayoutShiftsHandler.js.map +1 -1
- package/models/trace/handlers/MemoryHandler.d.ts +2 -2
- package/models/trace/handlers/MemoryHandler.js +1 -1
- package/models/trace/handlers/MemoryHandler.js.map +1 -1
- package/models/trace/handlers/MetaHandler.d.ts +15 -14
- package/models/trace/handlers/MetaHandler.js +32 -30
- package/models/trace/handlers/MetaHandler.js.map +1 -1
- package/models/trace/handlers/ModelHandlers.d.ts +1 -1
- package/models/trace/handlers/ModelHandlers.js +1 -1
- package/models/trace/handlers/ModelHandlers.js.map +1 -1
- package/models/trace/handlers/NetworkRequestsHandler.d.ts +13 -12
- package/models/trace/handlers/NetworkRequestsHandler.js +68 -66
- package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -1
- package/models/trace/handlers/PageFramesHandler.d.ts +2 -2
- package/models/trace/handlers/PageFramesHandler.js +2 -2
- package/models/trace/handlers/PageFramesHandler.js.map +1 -1
- package/models/trace/handlers/PageLoadMetricsHandler.d.ts +7 -7
- package/models/trace/handlers/PageLoadMetricsHandler.js +21 -24
- package/models/trace/handlers/PageLoadMetricsHandler.js.map +1 -1
- package/models/trace/handlers/RendererHandler.d.ts +19 -19
- package/models/trace/handlers/RendererHandler.js +5 -5
- package/models/trace/handlers/RendererHandler.js.map +1 -1
- package/models/trace/handlers/SamplesHandler.d.ts +6 -6
- package/models/trace/handlers/SamplesHandler.js +3 -3
- package/models/trace/handlers/SamplesHandler.js.map +1 -1
- package/models/trace/handlers/ScreenshotsHandler.d.ts +6 -4
- package/models/trace/handlers/ScreenshotsHandler.js +11 -9
- package/models/trace/handlers/ScreenshotsHandler.js.map +1 -1
- package/models/trace/handlers/SelectorStatsHandler.d.ts +3 -3
- package/models/trace/handlers/SelectorStatsHandler.js +2 -2
- package/models/trace/handlers/SelectorStatsHandler.js.map +1 -1
- package/models/trace/handlers/ServerTimingsHandler.d.ts +10 -0
- package/models/trace/handlers/ServerTimingsHandler.js +118 -0
- package/models/trace/handlers/ServerTimingsHandler.js.map +1 -0
- package/models/trace/handlers/Threads.d.ts +7 -7
- package/models/trace/handlers/Threads.js +5 -5
- package/models/trace/handlers/Threads.js.map +1 -1
- package/models/trace/handlers/UserInteractionsHandler.d.ts +13 -11
- package/models/trace/handlers/UserInteractionsHandler.js +13 -7
- package/models/trace/handlers/UserInteractionsHandler.js.map +1 -1
- package/models/trace/handlers/UserTimingsHandler.d.ts +5 -5
- package/models/trace/handlers/UserTimingsHandler.js +52 -9
- package/models/trace/handlers/UserTimingsHandler.js.map +1 -1
- package/models/trace/handlers/WarningsHandler.d.ts +5 -5
- package/models/trace/handlers/WarningsHandler.js +4 -5
- package/models/trace/handlers/WarningsHandler.js.map +1 -1
- package/models/trace/handlers/WorkersHandler.d.ts +4 -4
- package/models/trace/handlers/WorkersHandler.js +1 -1
- package/models/trace/handlers/WorkersHandler.js.map +1 -1
- package/models/trace/handlers/handlers-tsconfig.json +1 -1
- package/models/trace/handlers/types.d.ts +7 -7
- package/models/trace/handlers/types.js.map +1 -1
- package/models/trace/helpers/Extensions.d.ts +2 -2
- package/models/trace/helpers/Extensions.js.map +1 -1
- package/models/trace/helpers/Network.d.ts +2 -2
- package/models/trace/helpers/Network.js +19 -2
- package/models/trace/helpers/Network.js.map +1 -1
- package/models/trace/helpers/SamplesIntegrator.d.ts +5 -5
- package/models/trace/helpers/SamplesIntegrator.js +10 -11
- package/models/trace/helpers/SamplesIntegrator.js.map +1 -1
- package/models/trace/helpers/SyntheticEvents.d.ts +8 -14
- package/models/trace/helpers/SyntheticEvents.js +20 -31
- package/models/trace/helpers/SyntheticEvents.js.map +1 -1
- package/models/trace/helpers/Timing.d.ts +16 -4
- package/models/trace/helpers/Timing.js +33 -1
- package/models/trace/helpers/Timing.js.map +1 -1
- package/models/trace/helpers/Trace.d.ts +46 -32
- package/models/trace/helpers/Trace.js +53 -24
- package/models/trace/helpers/Trace.js.map +1 -1
- package/models/trace/helpers/TreeHelpers.d.ts +29 -8
- package/models/trace/helpers/TreeHelpers.js +87 -19
- package/models/trace/helpers/TreeHelpers.js.map +1 -1
- package/models/trace/insights/Common.d.ts +4 -3
- package/models/trace/insights/Common.js +22 -7
- package/models/trace/insights/Common.js.map +1 -1
- package/models/trace/insights/CumulativeLayoutShift.d.ts +34 -13
- package/models/trace/insights/CumulativeLayoutShift.js +151 -59
- package/models/trace/insights/CumulativeLayoutShift.js.map +1 -1
- package/models/trace/insights/DocumentLatency.d.ts +9 -4
- package/models/trace/insights/DocumentLatency.js +82 -7
- package/models/trace/insights/DocumentLatency.js.map +1 -1
- package/models/trace/insights/FontDisplay.d.ts +11 -0
- package/models/trace/insights/FontDisplay.js +44 -0
- package/models/trace/insights/FontDisplay.js.map +1 -0
- package/models/trace/insights/InsightRunners.d.ts +3 -0
- package/models/trace/insights/InsightRunners.js +3 -0
- package/models/trace/insights/InsightRunners.js.map +1 -1
- package/models/trace/insights/InteractionToNextPaint.d.ts +4 -5
- package/models/trace/insights/InteractionToNextPaint.js +5 -3
- package/models/trace/insights/InteractionToNextPaint.js.map +1 -1
- package/models/trace/insights/LargestContentfulPaint.d.ts +20 -7
- package/models/trace/insights/LargestContentfulPaint.js +57 -37
- package/models/trace/insights/LargestContentfulPaint.js.map +1 -1
- package/models/trace/insights/RenderBlocking.d.ts +3 -3
- package/models/trace/insights/RenderBlocking.js +29 -24
- package/models/trace/insights/RenderBlocking.js.map +1 -1
- package/models/trace/insights/SlowCSSSelector.d.ts +11 -0
- package/models/trace/insights/SlowCSSSelector.js +67 -0
- package/models/trace/insights/SlowCSSSelector.js.map +1 -0
- package/models/trace/insights/ThirdPartyWeb.d.ts +18 -0
- package/models/trace/insights/ThirdPartyWeb.js +174 -0
- package/models/trace/insights/ThirdPartyWeb.js.map +1 -0
- package/models/trace/insights/Viewport.d.ts +5 -2
- package/models/trace/insights/Viewport.js +14 -9
- package/models/trace/insights/Viewport.js.map +1 -1
- package/models/trace/insights/insights-tsconfig.json +9 -0
- 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 +43 -25
- package/models/trace/insights/types.js.map +1 -1
- package/models/trace/lantern/core/NetworkAnalyzer.d.ts +6 -6
- package/models/trace/lantern/core/NetworkAnalyzer.js +12 -12
- package/models/trace/lantern/core/NetworkAnalyzer.js.map +1 -1
- package/models/trace/lantern/graph/BaseNode.d.ts +4 -4
- package/models/trace/lantern/graph/BaseNode.js +21 -21
- package/models/trace/lantern/graph/BaseNode.js.map +1 -1
- package/models/trace/lantern/graph/CPUNode.d.ts +1 -1
- package/models/trace/lantern/graph/CPUNode.js +5 -5
- package/models/trace/lantern/graph/CPUNode.js.map +1 -1
- package/models/trace/lantern/graph/PageDependencyGraph.d.ts +4 -4
- package/models/trace/lantern/graph/PageDependencyGraph.js +5 -5
- package/models/trace/lantern/graph/PageDependencyGraph.js.map +1 -1
- package/models/trace/lantern/simulation/ConnectionPool.d.ts +7 -7
- package/models/trace/lantern/simulation/ConnectionPool.js +26 -26
- package/models/trace/lantern/simulation/ConnectionPool.js.map +1 -1
- package/models/trace/lantern/simulation/DNSCache.d.ts +3 -3
- package/models/trace/lantern/simulation/DNSCache.js +11 -11
- package/models/trace/lantern/simulation/DNSCache.js.map +1 -1
- package/models/trace/lantern/simulation/SimulationTimingMap.d.ts +1 -1
- package/models/trace/lantern/simulation/SimulationTimingMap.js +15 -15
- package/models/trace/lantern/simulation/SimulationTimingMap.js.map +1 -1
- package/models/trace/lantern/simulation/Simulator.d.ts +28 -28
- package/models/trace/lantern/simulation/Simulator.js +113 -113
- package/models/trace/lantern/simulation/Simulator.js.map +1 -1
- package/models/trace/lantern/simulation/TCPConnection.d.ts +9 -9
- package/models/trace/lantern/simulation/TCPConnection.js +36 -36
- package/models/trace/lantern/simulation/TCPConnection.js.map +1 -1
- package/models/trace/root-causes/LayoutShift.d.ts +13 -13
- package/models/trace/root-causes/LayoutShift.js +7 -25
- package/models/trace/root-causes/LayoutShift.js.map +1 -1
- package/models/trace/types/Configuration.d.ts +16 -0
- package/models/trace/types/Configuration.js +1 -0
- package/models/trace/types/Configuration.js.map +1 -1
- package/models/trace/types/Extensions.d.ts +9 -12
- package/models/trace/types/Extensions.js +2 -1
- package/models/trace/types/Extensions.js.map +1 -1
- package/models/trace/types/File.d.ts +55 -23
- package/models/trace/types/File.js +15 -3
- package/models/trace/types/File.js.map +1 -1
- package/models/trace/types/TraceEvents.d.ts +818 -713
- package/models/trace/types/TraceEvents.js +270 -277
- package/models/trace/types/TraceEvents.js.map +1 -1
- package/models/trace/types/types.d.ts +1 -1
- package/models/trace/types/types.js +1 -1
- package/models/trace/types/types.js.map +1 -1
- package/package.json +4 -2
- package/test/test-trace-engine.mjs +47 -2
- package/third_party/third-party-web/third-party-web.js +1 -0
- package/core/platform/PromiseUtilities.d.ts +0 -10
- package/core/platform/PromiseUtilities.js +0 -18
- package/core/platform/PromiseUtilities.js.map +0 -1
- package/core/platform/SetUtilities.d.ts +0 -2
- package/core/platform/SetUtilities.js +0 -23
- package/core/platform/SetUtilities.js.map +0 -1
- package/models/trace/EntriesFilter.d.ts +0 -72
- package/models/trace/EntriesFilter.js +0 -296
- package/models/trace/EntriesFilter.js.map +0 -1
- package/models/trace/LegacyTracingModel.js.map +0 -1
- package/models/trace/handlers/EnhancedTracesHandler.d.ts +0 -48
- package/models/trace/handlers/EnhancedTracesHandler.js +0 -165
- package/models/trace/handlers/EnhancedTracesHandler.js.map +0 -1
- package/models/trace/lantern/BaseNode.d.ts +0 -91
- package/models/trace/lantern/BaseNode.js +0 -268
- package/models/trace/lantern/BaseNode.js.map +0 -1
- package/models/trace/lantern/CPUNode.d.ts +0 -24
- package/models/trace/lantern/CPUNode.js +0 -64
- package/models/trace/lantern/CPUNode.js.map +0 -1
- package/models/trace/lantern/LanternError.d.ts +0 -3
- package/models/trace/lantern/LanternError.js +0 -7
- package/models/trace/lantern/LanternError.js.map +0 -1
- package/models/trace/lantern/MetricsModule.d.ts +0 -11
- package/models/trace/lantern/MetricsModule.js +0 -14
- package/models/trace/lantern/MetricsModule.js.map +0 -1
- package/models/trace/lantern/NetworkNode.d.ts +0 -22
- package/models/trace/lantern/NetworkNode.js +0 -83
- package/models/trace/lantern/NetworkNode.js.map +0 -1
- package/models/trace/lantern/PageDependencyGraph.d.ts +0 -43
- package/models/trace/lantern/PageDependencyGraph.js +0 -509
- package/models/trace/lantern/PageDependencyGraph.js.map +0 -1
- package/models/trace/lantern/SimulationModule.d.ts +0 -17
- package/models/trace/lantern/SimulationModule.js +0 -13
- package/models/trace/lantern/SimulationModule.js.map +0 -1
- package/models/trace/lantern/simulation/NetworkAnalyzer.d.ts +0 -112
- package/models/trace/lantern/simulation/NetworkAnalyzer.js +0 -486
- package/models/trace/lantern/simulation/NetworkAnalyzer.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SlowCSSSelector.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/SlowCSSSelector.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 Helpers from '../helpers/helpers.js';\nimport {type SelectorTiming, SelectorTimingsKey} from '../types/TraceEvents.js';\nimport * as Types from '../types/types.js';\n\nimport type {InsightResult, InsightSetContext, RequiredData} from './types.js';\n\nexport function deps(): ['SelectorStats'] {\n return ['SelectorStats'];\n}\n\nexport type SlowCSSSelectorInsightResult = InsightResult<{\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\nexport function generateInsight(\n parsedTrace: RequiredData<typeof deps>, context: InsightSetContext): SlowCSSSelectorInsightResult {\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.toSorted((a, b) => {\n return b[SelectorTimingsKey.Elapsed] - a[SelectorTimingsKey.Elapsed];\n });\n\n // sort by match attempts\n const sortByMatchAttempts = selectorTimings.toSorted((a, b) => {\n return b[SelectorTimingsKey.MatchAttempts] - a[SelectorTimingsKey.MatchAttempts];\n });\n\n return {\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,18 @@
|
|
|
1
|
+
import * as ThirdPartyWeb from '../../../third_party/third-party-web/third-party-web.js';
|
|
2
|
+
import * as Types from '../types/types.js';
|
|
3
|
+
import type { InsightResult, InsightSetContext, RequiredData } from './types.js';
|
|
4
|
+
export declare function deps(): ['Meta', 'NetworkRequests', 'Renderer', 'ImagePainting'];
|
|
5
|
+
export type Entity = typeof ThirdPartyWeb.ThirdPartyWeb.entities[number];
|
|
6
|
+
export interface Summary {
|
|
7
|
+
transferSize: number;
|
|
8
|
+
mainThreadTime: Types.Timing.MicroSeconds;
|
|
9
|
+
}
|
|
10
|
+
export type ThirdPartyWebInsightResult = InsightResult<{
|
|
11
|
+
entityByRequest: Map<Types.Events.SyntheticNetworkRequest, Entity>;
|
|
12
|
+
requestsByEntity: Map<Entity, Types.Events.SyntheticNetworkRequest[]>;
|
|
13
|
+
summaryByRequest: Map<Types.Events.SyntheticNetworkRequest, Summary>;
|
|
14
|
+
summaryByEntity: Map<Entity, Summary>;
|
|
15
|
+
/** The entity for this navigation's URL. Any other entity is from a third party. */
|
|
16
|
+
firstPartyEntity?: Entity;
|
|
17
|
+
}>;
|
|
18
|
+
export declare function generateInsight(parsedTrace: RequiredData<typeof deps>, context: InsightSetContext): ThirdPartyWebInsightResult;
|
|
@@ -0,0 +1,174 @@
|
|
|
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
|
+
import * as ThirdPartyWeb from '../../../third_party/third-party-web/third-party-web.js';
|
|
5
|
+
import * as Extras from '../extras/extras.js';
|
|
6
|
+
import * as Helpers from '../helpers/helpers.js';
|
|
7
|
+
import * as Types from '../types/types.js';
|
|
8
|
+
export function deps() {
|
|
9
|
+
return ['Meta', 'NetworkRequests', 'Renderer', 'ImagePainting'];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Returns the origin portion of a Chrome extension URL.
|
|
13
|
+
*/
|
|
14
|
+
function getChromeExtensionOrigin(url) {
|
|
15
|
+
return url.protocol + '//' + url.host;
|
|
16
|
+
}
|
|
17
|
+
function makeUpChromeExtensionEntity(entityCache, url, extensionName) {
|
|
18
|
+
const parsedUrl = new URL(url);
|
|
19
|
+
const origin = getChromeExtensionOrigin(parsedUrl);
|
|
20
|
+
const host = new URL(origin).host;
|
|
21
|
+
const name = extensionName || host;
|
|
22
|
+
const cachedEntity = entityCache.get(origin);
|
|
23
|
+
if (cachedEntity) {
|
|
24
|
+
return cachedEntity;
|
|
25
|
+
}
|
|
26
|
+
const chromeExtensionEntity = {
|
|
27
|
+
name,
|
|
28
|
+
company: name,
|
|
29
|
+
category: 'Chrome Extension',
|
|
30
|
+
homepage: 'https://chromewebstore.google.com/detail/' + host,
|
|
31
|
+
categories: [],
|
|
32
|
+
domains: [],
|
|
33
|
+
averageExecutionTime: 0,
|
|
34
|
+
totalExecutionTime: 0,
|
|
35
|
+
totalOccurrences: 0,
|
|
36
|
+
};
|
|
37
|
+
entityCache.set(origin, chromeExtensionEntity);
|
|
38
|
+
return chromeExtensionEntity;
|
|
39
|
+
}
|
|
40
|
+
function makeUpEntity(entityCache, url) {
|
|
41
|
+
if (url.startsWith('chrome-extension:')) {
|
|
42
|
+
return makeUpChromeExtensionEntity(entityCache, url);
|
|
43
|
+
}
|
|
44
|
+
// Make up an entity only for valid http/https URLs.
|
|
45
|
+
if (!url.startsWith('http')) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
// NOTE: Lighthouse uses a tld database to determine the root domain, but here
|
|
49
|
+
// we are using third party web's database. Doesn't really work for the case of classifying
|
|
50
|
+
// domains 3pweb doesn't know about, so it will just give us a guess.
|
|
51
|
+
const rootDomain = ThirdPartyWeb.ThirdPartyWeb.getRootDomain(url);
|
|
52
|
+
if (!rootDomain) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (entityCache.has(rootDomain)) {
|
|
56
|
+
return entityCache.get(rootDomain);
|
|
57
|
+
}
|
|
58
|
+
const unrecognizedEntity = {
|
|
59
|
+
name: rootDomain,
|
|
60
|
+
company: rootDomain,
|
|
61
|
+
category: '',
|
|
62
|
+
categories: [],
|
|
63
|
+
domains: [rootDomain],
|
|
64
|
+
averageExecutionTime: 0,
|
|
65
|
+
totalExecutionTime: 0,
|
|
66
|
+
totalOccurrences: 0,
|
|
67
|
+
isUnrecognized: true,
|
|
68
|
+
};
|
|
69
|
+
entityCache.set(rootDomain, unrecognizedEntity);
|
|
70
|
+
return unrecognizedEntity;
|
|
71
|
+
}
|
|
72
|
+
function getSelfTimeByUrl(parsedTrace, context) {
|
|
73
|
+
const selfTimeByUrl = new Map();
|
|
74
|
+
for (const process of parsedTrace.Renderer.processes.values()) {
|
|
75
|
+
if (!process.isOnMainFrame) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
for (const thread of process.threads.values()) {
|
|
79
|
+
if (thread.name === 'CrRendererMain') {
|
|
80
|
+
if (!thread.tree) {
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
for (const event of thread.entries) {
|
|
84
|
+
if (!Helpers.Timing.eventIsInBounds(event, context.bounds)) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const node = parsedTrace.Renderer.entryToNode.get(event);
|
|
88
|
+
if (!node || !node.selfTime) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const url = Extras.URLForEntry.getNonResolved(parsedTrace, event);
|
|
92
|
+
if (!url) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
selfTimeByUrl.set(url, node.selfTime + (selfTimeByUrl.get(url) ?? 0));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return selfTimeByUrl;
|
|
101
|
+
}
|
|
102
|
+
function getSummaries(requests, entityByRequest, selfTimeByUrl) {
|
|
103
|
+
const byRequest = new Map();
|
|
104
|
+
const byEntity = new Map();
|
|
105
|
+
const defaultSummary = { transferSize: 0, mainThreadTime: Types.Timing.MicroSeconds(0) };
|
|
106
|
+
for (const request of requests) {
|
|
107
|
+
const urlSummary = byRequest.get(request) || { ...defaultSummary };
|
|
108
|
+
urlSummary.transferSize += request.args.data.encodedDataLength;
|
|
109
|
+
urlSummary.mainThreadTime =
|
|
110
|
+
Types.Timing.MicroSeconds(urlSummary.mainThreadTime + (selfTimeByUrl.get(request.args.data.url) ?? 0));
|
|
111
|
+
byRequest.set(request, urlSummary);
|
|
112
|
+
}
|
|
113
|
+
// Map each request's stat to a particular entity.
|
|
114
|
+
const requestsByEntity = new Map();
|
|
115
|
+
for (const [request, requestSummary] of byRequest.entries()) {
|
|
116
|
+
const entity = entityByRequest.get(request);
|
|
117
|
+
if (!entity) {
|
|
118
|
+
byRequest.delete(request);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
const entitySummary = byEntity.get(entity) || { ...defaultSummary };
|
|
122
|
+
entitySummary.transferSize += requestSummary.transferSize;
|
|
123
|
+
entitySummary.mainThreadTime =
|
|
124
|
+
Types.Timing.MicroSeconds(entitySummary.mainThreadTime + requestSummary.mainThreadTime);
|
|
125
|
+
byEntity.set(entity, entitySummary);
|
|
126
|
+
const entityRequests = requestsByEntity.get(entity) || [];
|
|
127
|
+
entityRequests.push(request);
|
|
128
|
+
requestsByEntity.set(entity, entityRequests);
|
|
129
|
+
}
|
|
130
|
+
return { byEntity, byRequest, requestsByEntity };
|
|
131
|
+
}
|
|
132
|
+
function getRelatedEvents(summaries, firstPartyEntity) {
|
|
133
|
+
const events = [];
|
|
134
|
+
for (const [entity, requests] of summaries.requestsByEntity.entries()) {
|
|
135
|
+
if (entity !== firstPartyEntity) {
|
|
136
|
+
events.push(...requests);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return events;
|
|
140
|
+
}
|
|
141
|
+
export function generateInsight(parsedTrace, context) {
|
|
142
|
+
const networkRequests = parsedTrace.NetworkRequests.byTime.filter(event => {
|
|
143
|
+
if (!context.navigation) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
if (event.args.data.frame !== context.frameId) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
return Helpers.Timing.eventIsInBounds(event, context.bounds);
|
|
150
|
+
});
|
|
151
|
+
const entityByRequest = new Map();
|
|
152
|
+
const madeUpEntityCache = new Map();
|
|
153
|
+
for (const request of networkRequests) {
|
|
154
|
+
const url = request.args.data.url;
|
|
155
|
+
const entity = ThirdPartyWeb.ThirdPartyWeb.getEntity(url) ?? makeUpEntity(madeUpEntityCache, url);
|
|
156
|
+
if (entity) {
|
|
157
|
+
entityByRequest.set(request, entity);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
const selfTimeByUrl = getSelfTimeByUrl(parsedTrace, context);
|
|
161
|
+
// TODO(crbug.com/352244718): re-work to still collect main thread activity if no request is present
|
|
162
|
+
const summaries = getSummaries(networkRequests, entityByRequest, selfTimeByUrl);
|
|
163
|
+
const firstPartyUrl = context.navigation?.args.data?.documentLoaderURL ?? parsedTrace.Meta.mainFrameURL;
|
|
164
|
+
const firstPartyEntity = ThirdPartyWeb.ThirdPartyWeb.getEntity(firstPartyUrl) || makeUpEntity(madeUpEntityCache, firstPartyUrl);
|
|
165
|
+
return {
|
|
166
|
+
relatedEvents: getRelatedEvents(summaries, firstPartyEntity),
|
|
167
|
+
entityByRequest,
|
|
168
|
+
requestsByEntity: summaries.requestsByEntity,
|
|
169
|
+
summaryByRequest: summaries.byRequest,
|
|
170
|
+
summaryByEntity: summaries.byEntity,
|
|
171
|
+
firstPartyEntity,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=ThirdPartyWeb.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThirdPartyWeb.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/ThirdPartyWeb.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 ThirdPartyWeb from '../../../third_party/third-party-web/third-party-web.js';\nimport * as Extras from '../extras/extras.js';\nimport type * as Handlers from '../handlers/handlers.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport type {InsightResult, InsightSetContext, RequiredData} from './types.js';\n\nexport function deps(): ['Meta', 'NetworkRequests', 'Renderer', 'ImagePainting'] {\n return ['Meta', 'NetworkRequests', 'Renderer', 'ImagePainting'];\n}\n\nexport type Entity = typeof ThirdPartyWeb.ThirdPartyWeb.entities[number];\n\nexport interface Summary {\n transferSize: number;\n mainThreadTime: Types.Timing.MicroSeconds;\n}\n\nexport type ThirdPartyWebInsightResult = InsightResult<{\n entityByRequest: Map<Types.Events.SyntheticNetworkRequest, Entity>,\n requestsByEntity: Map<Entity, Types.Events.SyntheticNetworkRequest[]>,\n summaryByRequest: Map<Types.Events.SyntheticNetworkRequest, Summary>,\n summaryByEntity: Map<Entity, Summary>,\n /** The entity for this navigation's URL. Any other entity is from a third party. */\n firstPartyEntity?: Entity,\n}>;\n\n/**\n * Returns the origin portion of a Chrome extension URL.\n */\nfunction getChromeExtensionOrigin(url: URL): string {\n return url.protocol + '//' + url.host;\n}\n\nfunction makeUpChromeExtensionEntity(entityCache: Map<string, Entity>, url: string, extensionName?: string): Entity {\n const parsedUrl = new URL(url);\n const origin = getChromeExtensionOrigin(parsedUrl);\n const host = new URL(origin).host;\n const name = extensionName || host;\n\n const cachedEntity = entityCache.get(origin);\n if (cachedEntity) {\n return cachedEntity;\n }\n\n const chromeExtensionEntity = {\n name,\n company: name,\n category: 'Chrome Extension',\n homepage: 'https://chromewebstore.google.com/detail/' + host,\n categories: [],\n domains: [],\n averageExecutionTime: 0,\n totalExecutionTime: 0,\n totalOccurrences: 0,\n };\n\n entityCache.set(origin, chromeExtensionEntity);\n return chromeExtensionEntity;\n}\n\nfunction makeUpEntity(entityCache: Map<string, Entity>, url: string): Entity|undefined {\n if (url.startsWith('chrome-extension:')) {\n return makeUpChromeExtensionEntity(entityCache, url);\n }\n\n // Make up an entity only for valid http/https URLs.\n if (!url.startsWith('http')) {\n return;\n }\n\n // NOTE: Lighthouse uses a tld database to determine the root domain, but here\n // we are using third party web's database. Doesn't really work for the case of classifying\n // domains 3pweb doesn't know about, so it will just give us a guess.\n const rootDomain = ThirdPartyWeb.ThirdPartyWeb.getRootDomain(url);\n if (!rootDomain) {\n return;\n }\n\n if (entityCache.has(rootDomain)) {\n return entityCache.get(rootDomain);\n }\n\n const unrecognizedEntity = {\n name: rootDomain,\n company: rootDomain,\n category: '',\n categories: [],\n domains: [rootDomain],\n averageExecutionTime: 0,\n totalExecutionTime: 0,\n totalOccurrences: 0,\n isUnrecognized: true,\n };\n entityCache.set(rootDomain, unrecognizedEntity);\n return unrecognizedEntity;\n}\n\ninterface SummaryMaps {\n byEntity: Map<Entity, Summary>;\n byRequest: Map<Types.Events.SyntheticNetworkRequest, Summary>;\n requestsByEntity: Map<Entity, Types.Events.SyntheticNetworkRequest[]>;\n}\n\nfunction getSelfTimeByUrl(parsedTrace: RequiredData<typeof deps>, context: InsightSetContext): Map<string, number> {\n const selfTimeByUrl = new Map<string, number>();\n\n for (const process of parsedTrace.Renderer.processes.values()) {\n if (!process.isOnMainFrame) {\n continue;\n }\n\n for (const thread of process.threads.values()) {\n if (thread.name === 'CrRendererMain') {\n if (!thread.tree) {\n break;\n }\n\n for (const event of thread.entries) {\n if (!Helpers.Timing.eventIsInBounds(event, context.bounds)) {\n continue;\n }\n\n const node = parsedTrace.Renderer.entryToNode.get(event);\n if (!node || !node.selfTime) {\n continue;\n }\n\n const url = Extras.URLForEntry.getNonResolved(parsedTrace as Handlers.Types.ParsedTrace, event);\n if (!url) {\n continue;\n }\n\n selfTimeByUrl.set(url, node.selfTime + (selfTimeByUrl.get(url) ?? 0));\n }\n }\n }\n }\n\n return selfTimeByUrl;\n}\n\nfunction getSummaries(\n requests: Types.Events.SyntheticNetworkRequest[],\n entityByRequest: Map<Types.Events.SyntheticNetworkRequest, Entity>,\n selfTimeByUrl: Map<string, number>): SummaryMaps {\n const byRequest = new Map<Types.Events.SyntheticNetworkRequest, Summary>();\n const byEntity = new Map<Entity, Summary>();\n const defaultSummary: Summary = {transferSize: 0, mainThreadTime: Types.Timing.MicroSeconds(0)};\n\n for (const request of requests) {\n const urlSummary = byRequest.get(request) || {...defaultSummary};\n urlSummary.transferSize += request.args.data.encodedDataLength;\n urlSummary.mainThreadTime =\n Types.Timing.MicroSeconds(urlSummary.mainThreadTime + (selfTimeByUrl.get(request.args.data.url) ?? 0));\n byRequest.set(request, urlSummary);\n }\n\n // Map each request's stat to a particular entity.\n const requestsByEntity = new Map<Entity, Types.Events.SyntheticNetworkRequest[]>();\n for (const [request, requestSummary] of byRequest.entries()) {\n const entity = entityByRequest.get(request);\n if (!entity) {\n byRequest.delete(request);\n continue;\n }\n\n const entitySummary = byEntity.get(entity) || {...defaultSummary};\n entitySummary.transferSize += requestSummary.transferSize;\n entitySummary.mainThreadTime =\n Types.Timing.MicroSeconds(entitySummary.mainThreadTime + requestSummary.mainThreadTime);\n byEntity.set(entity, entitySummary);\n\n const entityRequests = requestsByEntity.get(entity) || [];\n entityRequests.push(request);\n requestsByEntity.set(entity, entityRequests);\n }\n\n return {byEntity, byRequest, requestsByEntity};\n}\n\nfunction getRelatedEvents(summaries: SummaryMaps, firstPartyEntity: Entity|undefined): Types.Events.Event[] {\n const events = [];\n\n for (const [entity, requests] of summaries.requestsByEntity.entries()) {\n if (entity !== firstPartyEntity) {\n events.push(...requests);\n }\n }\n\n return events;\n}\n\nexport function generateInsight(\n parsedTrace: RequiredData<typeof deps>, context: InsightSetContext): ThirdPartyWebInsightResult {\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 = new Map<Types.Events.SyntheticNetworkRequest, Entity>();\n const madeUpEntityCache = new Map<string, Entity>();\n for (const request of networkRequests) {\n const url = request.args.data.url;\n const entity = ThirdPartyWeb.ThirdPartyWeb.getEntity(url) ?? makeUpEntity(madeUpEntityCache, url);\n if (entity) {\n entityByRequest.set(request, entity);\n }\n }\n\n const selfTimeByUrl = getSelfTimeByUrl(parsedTrace, context);\n // TODO(crbug.com/352244718): re-work to still collect main thread activity if no request is present\n const summaries = getSummaries(networkRequests, entityByRequest, selfTimeByUrl);\n\n const firstPartyUrl = context.navigation?.args.data?.documentLoaderURL ?? parsedTrace.Meta.mainFrameURL;\n const firstPartyEntity =\n ThirdPartyWeb.ThirdPartyWeb.getEntity(firstPartyUrl) || makeUpEntity(madeUpEntityCache, firstPartyUrl);\n\n return {\n relatedEvents: getRelatedEvents(summaries, firstPartyEntity),\n entityByRequest,\n requestsByEntity: summaries.requestsByEntity,\n summaryByRequest: summaries.byRequest,\n summaryByEntity: summaries.byEntity,\n firstPartyEntity,\n };\n}\n"]}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type * as Types from '../types/types.js';
|
|
2
|
+
import { type InsightResult, type InsightSetContext, type RequiredData } from './types.js';
|
|
2
3
|
export declare function deps(): ['Meta', 'UserInteractions'];
|
|
3
|
-
export
|
|
4
|
+
export type ViewportInsightResult = InsightResult<{
|
|
4
5
|
mobileOptimized: boolean | null;
|
|
6
|
+
viewportEvent?: Types.Events.ParseMetaViewport;
|
|
5
7
|
}>;
|
|
8
|
+
export declare function generateInsight(parsedTrace: RequiredData<typeof deps>, context: InsightSetContext): ViewportInsightResult;
|
|
@@ -6,34 +6,39 @@ import { InsightWarning } from './types.js';
|
|
|
6
6
|
export function deps() {
|
|
7
7
|
return ['Meta', 'UserInteractions'];
|
|
8
8
|
}
|
|
9
|
-
export function generateInsight(
|
|
10
|
-
const
|
|
9
|
+
export function generateInsight(parsedTrace, context) {
|
|
10
|
+
const compositorEvents = parsedTrace.UserInteractions.beginCommitCompositorFrameEvents.filter(event => {
|
|
11
11
|
if (event.args.frame !== context.frameId) {
|
|
12
12
|
return false;
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
if (navigation?.args.data?.navigationId !== context.navigationId) {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
return true;
|
|
14
|
+
return Helpers.Timing.eventIsInBounds(event, context.bounds);
|
|
19
15
|
});
|
|
20
|
-
if (!
|
|
16
|
+
if (!compositorEvents.length) {
|
|
21
17
|
// Trace doesn't have the data we need.
|
|
22
18
|
return {
|
|
23
19
|
mobileOptimized: null,
|
|
24
20
|
warnings: [InsightWarning.NO_LAYOUT],
|
|
25
21
|
};
|
|
26
22
|
}
|
|
23
|
+
const viewportEvent = parsedTrace.UserInteractions.parseMetaViewportEvents.find(event => {
|
|
24
|
+
if (event.args.data.frame !== context.frameId) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
return Helpers.Timing.eventIsInBounds(event, context.bounds);
|
|
28
|
+
});
|
|
27
29
|
// Returns true only if all events are mobile optimized.
|
|
28
|
-
for (const event of
|
|
30
|
+
for (const event of compositorEvents) {
|
|
29
31
|
if (!event.args.is_mobile_optimized) {
|
|
30
32
|
return {
|
|
31
33
|
mobileOptimized: false,
|
|
34
|
+
viewportEvent,
|
|
35
|
+
metricSavings: { INP: 300 },
|
|
32
36
|
};
|
|
33
37
|
}
|
|
34
38
|
}
|
|
35
39
|
return {
|
|
36
40
|
mobileOptimized: true,
|
|
41
|
+
viewportEvent,
|
|
37
42
|
};
|
|
38
43
|
}
|
|
39
44
|
//# sourceMappingURL=Viewport.js.map
|
|
@@ -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,OAAO,MAAM,uBAAuB,CAAC;
|
|
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,OAAO,MAAM,uBAAuB,CAAC;AAGjD,OAAO,EAA6C,cAAc,EAAoB,MAAM,YAAY,CAAC;AAEzG,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;AACtC,CAAC;AAOD,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;YACL,eAAe,EAAE,IAAI;YACrB,QAAQ,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC;SACrC,CAAC;IACJ,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;gBACL,eAAe,EAAE,KAAK;gBACtB,aAAa;gBACb,aAAa,EAAE,EAAC,GAAG,EAAE,GAAgC,EAAC;aACvD,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO;QACL,eAAe,EAAE,IAAI;QACrB,aAAa;KACd,CAAC;AACJ,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 Helpers from '../helpers/helpers.js';\nimport type * as Types from '../types/types.js';\n\nimport {type InsightResult, type InsightSetContext, InsightWarning, type RequiredData} from './types.js';\n\nexport function deps(): ['Meta', 'UserInteractions'] {\n return ['Meta', 'UserInteractions'];\n}\n\nexport type ViewportInsightResult = InsightResult<{\n mobileOptimized: boolean | null,\n viewportEvent?: Types.Events.ParseMetaViewport,\n}>;\n\nexport function generateInsight(\n parsedTrace: RequiredData<typeof deps>, context: InsightSetContext): ViewportInsightResult {\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 {\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 {\n mobileOptimized: false,\n viewportEvent,\n metricSavings: {INP: 300 as Types.Timing.MilliSeconds},\n };\n }\n }\n\n return {\n mobileOptimized: true,\n viewportEvent,\n };\n}\n"]}
|
|
@@ -32,10 +32,13 @@
|
|
|
32
32
|
"../../../../../../../front_end/models/trace/insights/Common.ts",
|
|
33
33
|
"../../../../../../../front_end/models/trace/insights/CumulativeLayoutShift.ts",
|
|
34
34
|
"../../../../../../../front_end/models/trace/insights/DocumentLatency.ts",
|
|
35
|
+
"../../../../../../../front_end/models/trace/insights/FontDisplay.ts",
|
|
35
36
|
"../../../../../../../front_end/models/trace/insights/InsightRunners.ts",
|
|
36
37
|
"../../../../../../../front_end/models/trace/insights/InteractionToNextPaint.ts",
|
|
37
38
|
"../../../../../../../front_end/models/trace/insights/LargestContentfulPaint.ts",
|
|
38
39
|
"../../../../../../../front_end/models/trace/insights/RenderBlocking.ts",
|
|
40
|
+
"../../../../../../../front_end/models/trace/insights/SlowCSSSelector.ts",
|
|
41
|
+
"../../../../../../../front_end/models/trace/insights/ThirdPartyWeb.ts",
|
|
39
42
|
"../../../../../../../front_end/models/trace/insights/Viewport.ts",
|
|
40
43
|
"../../../../../../../front_end/models/trace/insights/types.ts",
|
|
41
44
|
"../../../../../../../front_end/legacy/legacy-defs.d.ts",
|
|
@@ -43,6 +46,12 @@
|
|
|
43
46
|
"../../../../../../../node_modules/@types/filesystem/index.d.ts"
|
|
44
47
|
],
|
|
45
48
|
"references": [
|
|
49
|
+
{
|
|
50
|
+
"path": "../../../third_party/third-party-web/bundle-tsconfig.json"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"path": "../extras/bundle-tsconfig.json"
|
|
54
|
+
},
|
|
46
55
|
{
|
|
47
56
|
"path": "../handlers/bundle-tsconfig.json"
|
|
48
57
|
},
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Copyright 2024 The Chromium Authors. All rights reserved.
|
|
2
2
|
// Use of this source code is governed by a BSD-style license that can be
|
|
3
3
|
// found in the LICENSE file.
|
|
4
|
+
export * as Common from './Common.js';
|
|
4
5
|
export * as InsightRunners from './InsightRunners.js';
|
|
5
6
|
export * as Types from './types.js';
|
|
6
7
|
//# sourceMappingURL=insights.js.map
|
|
@@ -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,cAAc,MAAM,qBAAqB,CAAC;AACtD,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 InsightRunners from './InsightRunners.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,cAAc,MAAM,qBAAqB,CAAC;AACtD,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 InsightRunners from './InsightRunners.js';\nexport * as Types from './types.js';\n"]}
|
|
@@ -3,16 +3,24 @@ import type * as Lantern from '../lantern/lantern.js';
|
|
|
3
3
|
import type * as Types from '../types/types.js';
|
|
4
4
|
import type * as InsightsRunners from './InsightRunners.js';
|
|
5
5
|
/**
|
|
6
|
-
* Context for
|
|
6
|
+
* Context for the portion of the trace an insight should look at.
|
|
7
7
|
*/
|
|
8
|
-
export
|
|
8
|
+
export type InsightSetContext = InsightSetContextWithoutNavigation | InsightSetContextWithNavigation;
|
|
9
|
+
export interface InsightSetContextWithoutNavigation {
|
|
10
|
+
bounds: Types.Timing.TraceWindowMicroSeconds;
|
|
9
11
|
frameId: string;
|
|
12
|
+
navigation?: never;
|
|
13
|
+
}
|
|
14
|
+
export interface InsightSetContextWithNavigation {
|
|
15
|
+
bounds: Types.Timing.TraceWindowMicroSeconds;
|
|
16
|
+
frameId: string;
|
|
17
|
+
navigation: Types.Events.NavigationStart;
|
|
10
18
|
navigationId: string;
|
|
11
19
|
lantern?: LanternContext;
|
|
12
20
|
}
|
|
13
21
|
export interface LanternContext {
|
|
14
|
-
graph: Lantern.Graph.Node<Types.
|
|
15
|
-
simulator: Lantern.Simulation.Simulator<Types.
|
|
22
|
+
graph: Lantern.Graph.Node<Types.Events.SyntheticNetworkRequest>;
|
|
23
|
+
simulator: Lantern.Simulation.Simulator<Types.Events.SyntheticNetworkRequest>;
|
|
16
24
|
metrics: Record<string, Lantern.Metrics.MetricResult>;
|
|
17
25
|
}
|
|
18
26
|
export type InsightRunnersType = typeof InsightsRunners;
|
|
@@ -22,36 +30,46 @@ export declare enum InsightWarning {
|
|
|
22
30
|
NO_DOCUMENT_REQUEST = "NO_DOCUMENT_REQUEST",
|
|
23
31
|
NO_LAYOUT = "NO_LAYOUT"
|
|
24
32
|
}
|
|
33
|
+
export interface MetricSavings {
|
|
34
|
+
FCP?: Types.Timing.MilliSeconds;
|
|
35
|
+
LCP?: Types.Timing.MilliSeconds;
|
|
36
|
+
TBT?: Types.Timing.MilliSeconds;
|
|
37
|
+
CLS?: number;
|
|
38
|
+
INP?: Types.Timing.MilliSeconds;
|
|
39
|
+
}
|
|
25
40
|
export type InsightResult<R extends Record<string, unknown>> = R & {
|
|
41
|
+
relatedEvents?: Types.Events.Event[];
|
|
26
42
|
warnings?: InsightWarning[];
|
|
27
|
-
metricSavings?:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
43
|
+
metricSavings?: MetricSavings;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Contains insights for a specific navigation. If a trace began after a navigation already started,
|
|
47
|
+
* this could instead represent the duration from the beginning of the trace up to the first recorded
|
|
48
|
+
* navigation (or the end of the trace).
|
|
49
|
+
*/
|
|
50
|
+
export type InsightSets = {
|
|
51
|
+
/** If for a navigation, this is the navigationId. Else it is Trace.Types.Events.NO_NAVIGATION. */
|
|
52
|
+
id: Types.Events.NavigationId;
|
|
53
|
+
/** The URL to show in the accordion list. */
|
|
54
|
+
url: URL;
|
|
55
|
+
frameId: string;
|
|
56
|
+
bounds: Types.Timing.TraceWindowMicroSeconds;
|
|
57
|
+
data: InsightResults;
|
|
58
|
+
navigation?: Types.Events.NavigationStart;
|
|
34
59
|
};
|
|
35
|
-
export type LCPInsightResult = InsightResult<{
|
|
36
|
-
lcpMs?: Types.Timing.MilliSeconds;
|
|
37
|
-
lcpTs?: Types.Timing.MilliSeconds;
|
|
38
|
-
phases?: InsightsRunners.LargestContentfulPaint.LCPPhases;
|
|
39
|
-
shouldRemoveLazyLoading?: boolean;
|
|
40
|
-
shouldIncreasePriorityHint?: boolean;
|
|
41
|
-
shouldPreloadImage?: boolean;
|
|
42
|
-
lcpResource?: Types.TraceEvents.SyntheticNetworkRequest;
|
|
43
|
-
earliestDiscoveryTimeTs?: Types.Timing.MicroSeconds;
|
|
44
|
-
}>;
|
|
45
60
|
/**
|
|
46
61
|
* Contains insights for a specific navigation.
|
|
47
62
|
*/
|
|
48
|
-
export type
|
|
49
|
-
[I in keyof InsightRunnersType]: ReturnType<InsightRunnersType[I]['generateInsight']
|
|
63
|
+
export type InsightResults = {
|
|
64
|
+
[I in keyof InsightRunnersType]: ReturnType<InsightRunnersType[I]['generateInsight']>;
|
|
50
65
|
};
|
|
51
66
|
/**
|
|
52
|
-
* Contains insights for the entire trace. Insights are grouped by `navigationId
|
|
67
|
+
* Contains insights for the entire trace. Insights are mostly grouped by `navigationId`, with one exception:
|
|
68
|
+
*
|
|
69
|
+
* If the analyzed trace started after the navigation, and has meaningful work with that span, there is no
|
|
70
|
+
* navigation to map it to. In this case `Types.Events.NO_NAVIGATION` is used for the key.
|
|
53
71
|
*/
|
|
54
|
-
export type
|
|
72
|
+
export type TraceInsightSets = Map<Types.Events.NavigationId, InsightSets>;
|
|
55
73
|
/**
|
|
56
74
|
* Represents the narrow set of dependencies defined by an insight's `deps()` function. `Meta` is always included regardless of `deps()`.
|
|
57
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;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/insights/types.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAmC7B,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","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 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 InsightsRunners from './InsightRunners.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 InsightRunnersType = typeof InsightsRunners;\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 type InsightResult<R extends Record<string, unknown>> = R&{\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 type InsightSets = {\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 data: InsightResults,\n navigation?: Types.Events.NavigationStart,\n};\n\n/**\n * Contains insights for a specific navigation.\n */\nexport type InsightResults = {\n [I in keyof InsightRunnersType]: ReturnType<InsightRunnersType[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, InsightSets>;\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"]}
|
|
@@ -34,7 +34,7 @@ declare class NetworkAnalyzer {
|
|
|
34
34
|
static groupByOrigin(records: Lantern.NetworkRequest[]): Map<string, Lantern.NetworkRequest[]>;
|
|
35
35
|
static getSummary(values: number[]): Summary;
|
|
36
36
|
static summarize(values: Map<string, number[]>): Map<string, Summary>;
|
|
37
|
-
static
|
|
37
|
+
static estimateValueByOrigin(requests: Lantern.NetworkRequest[], iteratee: (e: RequestInfo) => number | number[] | undefined): Map<string, number[]>;
|
|
38
38
|
/**
|
|
39
39
|
* Estimates the observed RTT to each origin based on how long the connection setup.
|
|
40
40
|
* For h1 and h2, this could includes two estimates - one for the TCP handshake, another for
|
|
@@ -43,31 +43,31 @@ declare class NetworkAnalyzer {
|
|
|
43
43
|
* single handshake.
|
|
44
44
|
* This is the most accurate and preferred method of measurement when the data is available.
|
|
45
45
|
*/
|
|
46
|
-
static
|
|
46
|
+
static estimateRTTViaConnectionTiming(info: RequestInfo): number[] | number | undefined;
|
|
47
47
|
/**
|
|
48
48
|
* Estimates the observed RTT to each origin based on how long a download took on a fresh connection.
|
|
49
49
|
* NOTE: this will tend to overestimate the actual RTT quite significantly as the download can be
|
|
50
50
|
* slow for other reasons as well such as bandwidth constraints.
|
|
51
51
|
*/
|
|
52
|
-
static
|
|
52
|
+
static estimateRTTViaDownloadTiming(info: RequestInfo): number | undefined;
|
|
53
53
|
/**
|
|
54
54
|
* Estimates the observed RTT to each origin based on how long it took until Chrome could
|
|
55
55
|
* start sending the actual request when a new connection was required.
|
|
56
56
|
* NOTE: this will tend to overestimate the actual RTT as the request can be delayed for other
|
|
57
57
|
* reasons as well such as more SSL handshakes if TLS False Start is not enabled.
|
|
58
58
|
*/
|
|
59
|
-
static
|
|
59
|
+
static estimateRTTViaSendStartTiming(info: RequestInfo): number | undefined;
|
|
60
60
|
/**
|
|
61
61
|
* Estimates the observed RTT to each origin based on how long it took until Chrome received the
|
|
62
62
|
* headers of the response (~TTFB).
|
|
63
63
|
* NOTE: this is the most inaccurate way to estimate the RTT, but in some environments it's all
|
|
64
64
|
* we have access to :(
|
|
65
65
|
*/
|
|
66
|
-
static
|
|
66
|
+
static estimateRTTViaHeadersEndTiming(info: RequestInfo): number | undefined;
|
|
67
67
|
/**
|
|
68
68
|
* Given the RTT to each origin, estimates the observed server response times.
|
|
69
69
|
*/
|
|
70
|
-
static
|
|
70
|
+
static estimateResponseTimeByOrigin(records: Lantern.NetworkRequest[], rttByOrigin: Map<string, number>): Map<string, number[]>;
|
|
71
71
|
static canTrustConnectionInformation(requests: Lantern.NetworkRequest[]): boolean;
|
|
72
72
|
/**
|
|
73
73
|
* Returns a map of requestId -> connectionReused, estimating the information if the information
|
|
@@ -93,7 +93,7 @@ class NetworkAnalyzer {
|
|
|
93
93
|
summaryByKey.set(NetworkAnalyzer.summary, NetworkAnalyzer.getSummary(allEstimates));
|
|
94
94
|
return summaryByKey;
|
|
95
95
|
}
|
|
96
|
-
static
|
|
96
|
+
static estimateValueByOrigin(requests, iteratee) {
|
|
97
97
|
const connectionWasReused = NetworkAnalyzer.estimateIfConnectionWasReused(requests);
|
|
98
98
|
const groupedByOrigin = NetworkAnalyzer.groupByOrigin(requests);
|
|
99
99
|
const estimates = new Map();
|
|
@@ -128,7 +128,7 @@ class NetworkAnalyzer {
|
|
|
128
128
|
* single handshake.
|
|
129
129
|
* This is the most accurate and preferred method of measurement when the data is available.
|
|
130
130
|
*/
|
|
131
|
-
static
|
|
131
|
+
static estimateRTTViaConnectionTiming(info) {
|
|
132
132
|
const { timing, connectionReused, request } = info;
|
|
133
133
|
if (connectionReused) {
|
|
134
134
|
return;
|
|
@@ -152,7 +152,7 @@ class NetworkAnalyzer {
|
|
|
152
152
|
* NOTE: this will tend to overestimate the actual RTT quite significantly as the download can be
|
|
153
153
|
* slow for other reasons as well such as bandwidth constraints.
|
|
154
154
|
*/
|
|
155
|
-
static
|
|
155
|
+
static estimateRTTViaDownloadTiming(info) {
|
|
156
156
|
const { timing, connectionReused, request } = info;
|
|
157
157
|
if (connectionReused) {
|
|
158
158
|
return;
|
|
@@ -181,7 +181,7 @@ class NetworkAnalyzer {
|
|
|
181
181
|
* NOTE: this will tend to overestimate the actual RTT as the request can be delayed for other
|
|
182
182
|
* reasons as well such as more SSL handshakes if TLS False Start is not enabled.
|
|
183
183
|
*/
|
|
184
|
-
static
|
|
184
|
+
static estimateRTTViaSendStartTiming(info) {
|
|
185
185
|
const { timing, connectionReused, request } = info;
|
|
186
186
|
if (connectionReused) {
|
|
187
187
|
return;
|
|
@@ -207,7 +207,7 @@ class NetworkAnalyzer {
|
|
|
207
207
|
* NOTE: this is the most inaccurate way to estimate the RTT, but in some environments it's all
|
|
208
208
|
* we have access to :(
|
|
209
209
|
*/
|
|
210
|
-
static
|
|
210
|
+
static estimateRTTViaHeadersEndTiming(info) {
|
|
211
211
|
const { timing, connectionReused, request } = info;
|
|
212
212
|
if (!Number.isFinite(timing.receiveHeadersEnd) || timing.receiveHeadersEnd < 0) {
|
|
213
213
|
return;
|
|
@@ -237,8 +237,8 @@ class NetworkAnalyzer {
|
|
|
237
237
|
/**
|
|
238
238
|
* Given the RTT to each origin, estimates the observed server response times.
|
|
239
239
|
*/
|
|
240
|
-
static
|
|
241
|
-
return NetworkAnalyzer.
|
|
240
|
+
static estimateResponseTimeByOrigin(records, rttByOrigin) {
|
|
241
|
+
return NetworkAnalyzer.estimateValueByOrigin(records, ({ request, timing }) => {
|
|
242
242
|
if (request.serverResponseTime !== undefined) {
|
|
243
243
|
return request.serverResponseTime;
|
|
244
244
|
}
|
|
@@ -334,7 +334,7 @@ class NetworkAnalyzer {
|
|
|
334
334
|
}
|
|
335
335
|
}
|
|
336
336
|
if (!forceCoarseEstimates) {
|
|
337
|
-
collectEstimates(this.
|
|
337
|
+
collectEstimates(this.estimateRTTViaConnectionTiming);
|
|
338
338
|
}
|
|
339
339
|
// Connection timing can be missing for a few reasons:
|
|
340
340
|
// - Origin was preconnected, which we don't have instrumentation for.
|
|
@@ -343,13 +343,13 @@ class NetworkAnalyzer {
|
|
|
343
343
|
// - Not provided in LR netstack.
|
|
344
344
|
if (!originEstimates.length) {
|
|
345
345
|
if (useDownloadEstimates) {
|
|
346
|
-
collectEstimates(this.
|
|
346
|
+
collectEstimates(this.estimateRTTViaDownloadTiming, coarseEstimateMultiplier);
|
|
347
347
|
}
|
|
348
348
|
if (useSendStartEstimates) {
|
|
349
|
-
collectEstimates(this.
|
|
349
|
+
collectEstimates(this.estimateRTTViaSendStartTiming, coarseEstimateMultiplier);
|
|
350
350
|
}
|
|
351
351
|
if (useHeadersEndEstimates) {
|
|
352
|
-
collectEstimates(this.
|
|
352
|
+
collectEstimates(this.estimateRTTViaHeadersEndTiming, coarseEstimateMultiplier);
|
|
353
353
|
}
|
|
354
354
|
}
|
|
355
355
|
if (originEstimates.length) {
|
|
@@ -374,7 +374,7 @@ class NetworkAnalyzer {
|
|
|
374
374
|
rttByOrigin.set(origin, summary.min);
|
|
375
375
|
}
|
|
376
376
|
}
|
|
377
|
-
const estimatesByOrigin = NetworkAnalyzer.
|
|
377
|
+
const estimatesByOrigin = NetworkAnalyzer.estimateResponseTimeByOrigin(records, rttByOrigin);
|
|
378
378
|
return NetworkAnalyzer.summarize(estimatesByOrigin);
|
|
379
379
|
}
|
|
380
380
|
/**
|