@paulirish/trace_engine 0.0.54 → 0.0.56
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/models/trace/extras/polyfills.d.ts +4 -0
- package/.tmp/tsbuildinfo/models/trace/extras/polyfills.d.ts.map +1 -0
- package/.tmp/tsbuildinfo/tsconfig.tsbuildinfo +1 -1
- package/core/platform/MimeType.d.ts +3 -2
- package/core/platform/MimeType.js +4 -3
- package/core/platform/MimeType.js.map +1 -1
- package/core/platform/devtools_entrypoint-bundle-tsconfig-tsconfig.json +43 -0
- package/core/platform/platform.prebundle.d.ts +18 -0
- package/core/platform/platform.prebundle.js +53 -0
- package/core/platform/platform.prebundle.js.map +1 -0
- package/core/platform/platform.prebundle.ts +71 -0
- package/generated/protocol.d.ts +115 -16
- package/locales/af.json +52 -10
- package/locales/am.json +52 -10
- package/locales/ar.json +51 -9
- package/locales/as.json +52 -10
- package/locales/az.json +52 -10
- package/locales/be.json +52 -10
- package/locales/bg.json +52 -10
- package/locales/bn.json +52 -10
- package/locales/bs.json +52 -10
- package/locales/ca.json +52 -10
- package/locales/cs.json +52 -10
- package/locales/cy.json +52 -10
- package/locales/da.json +52 -10
- package/locales/de.json +52 -10
- package/locales/el.json +52 -10
- package/locales/en-GB.json +52 -10
- package/locales/en-US.json +70 -58
- package/locales/en-XL.json +70 -58
- package/locales/es-419.json +52 -10
- package/locales/es.json +50 -8
- package/locales/et.json +52 -10
- package/locales/eu.json +52 -10
- package/locales/fa.json +51 -9
- package/locales/fi.json +52 -10
- package/locales/fil.json +52 -10
- package/locales/fr-CA.json +52 -10
- package/locales/fr.json +52 -10
- package/locales/gl.json +52 -10
- package/locales/gu.json +52 -10
- package/locales/he.json +52 -10
- package/locales/hi.json +52 -10
- package/locales/hr.json +52 -10
- package/locales/hu.json +51 -9
- package/locales/hy.json +51 -9
- package/locales/id.json +52 -10
- package/locales/is.json +53 -11
- package/locales/it.json +51 -9
- package/locales/ja.json +52 -10
- package/locales/ka.json +53 -11
- package/locales/kk.json +51 -9
- package/locales/km.json +52 -10
- package/locales/kn.json +52 -10
- package/locales/ko.json +52 -10
- package/locales/ky.json +51 -9
- package/locales/lo.json +52 -10
- package/locales/lt.json +52 -10
- package/locales/lv.json +51 -9
- package/locales/mk.json +52 -10
- package/locales/ml.json +53 -11
- package/locales/mn.json +52 -10
- package/locales/mr.json +52 -10
- package/locales/ms.json +52 -10
- package/locales/my.json +51 -9
- package/locales/ne.json +52 -10
- package/locales/nl.json +52 -10
- package/locales/no.json +52 -10
- package/locales/or.json +53 -11
- package/locales/pa.json +53 -11
- package/locales/pl.json +51 -9
- package/locales/pt-PT.json +52 -10
- package/locales/pt.json +52 -10
- package/locales/ro.json +52 -10
- package/locales/ru.json +53 -11
- package/locales/si.json +52 -10
- package/locales/sk.json +51 -9
- package/locales/sl.json +51 -9
- package/locales/sq.json +52 -10
- package/locales/sr-Latn.json +52 -10
- package/locales/sr.json +52 -10
- package/locales/sv.json +52 -10
- package/locales/sw.json +51 -9
- package/locales/ta.json +52 -10
- package/locales/te.json +52 -10
- package/locales/th.json +51 -9
- package/locales/tr.json +52 -10
- package/locales/uk.json +52 -10
- package/locales/ur.json +52 -10
- package/locales/uz.json +51 -9
- package/locales/vi.json +52 -10
- package/locales/zh-HK.json +52 -10
- package/locales/zh-TW.json +51 -9
- package/locales/zh.json +52 -10
- package/locales/zu.json +52 -10
- package/models/cpu_profile/CPUProfileDataModel.d.ts +4 -2
- package/models/cpu_profile/CPUProfileDataModel.js.map +1 -1
- package/models/cpu_profile/ProfileTreeModel.d.ts +0 -1
- package/models/cpu_profile/ProfileTreeModel.js +0 -2
- package/models/cpu_profile/ProfileTreeModel.js.map +1 -1
- package/models/cpu_profile/cpu_profile.prebundle.d.ts +3 -0
- package/models/cpu_profile/cpu_profile.prebundle.js +7 -0
- package/models/cpu_profile/cpu_profile.prebundle.js.map +1 -0
- package/models/cpu_profile/cpu_profile.prebundle.ts +11 -0
- package/models/cpu_profile/devtools_entrypoint-bundle-tsconfig-tsconfig.json +43 -0
- package/models/trace/LanternComputationData.js +7 -6
- package/models/trace/LanternComputationData.js.map +1 -1
- package/models/trace/Processor.js +25 -18
- package/models/trace/Processor.js.map +1 -1
- package/models/trace/devtools_entrypoint-bundle-tsconfig-tsconfig.json +61 -0
- package/models/trace/{root-causes/devtools_entrypoint-bundle-typescript-tsconfig.json → extras/devtools_entrypoint-bundle-tsconfig-tsconfig.json} +5 -4
- package/models/trace/extras/extras-tsconfig.json +0 -2
- package/models/trace/extras/extras.js.map +1 -1
- package/models/trace/extras/extras.prebundle.d.ts +7 -0
- package/models/trace/extras/extras.prebundle.js +11 -0
- package/models/trace/extras/extras.prebundle.js.map +1 -0
- package/models/trace/extras/extras.prebundle.ts +11 -0
- package/models/trace/handlers/ImagePaintingHandler.d.ts +7 -1
- package/models/trace/handlers/ImagePaintingHandler.js +33 -1
- package/models/trace/handlers/ImagePaintingHandler.js.map +1 -1
- package/models/trace/handlers/MetaHandler.js +2 -0
- package/models/trace/handlers/MetaHandler.js.map +1 -1
- package/models/trace/handlers/NetworkRequestsHandler.d.ts +0 -5
- package/models/trace/handlers/NetworkRequestsHandler.js +61 -20
- package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -1
- package/models/trace/handlers/SamplesHandler.js +7 -2
- package/models/trace/handlers/SamplesHandler.js.map +1 -1
- package/models/trace/handlers/ScriptsHandler.js.map +1 -1
- package/models/trace/{root-causes/root-causes-tsconfig.json → handlers/devtools_entrypoint-bundle-tsconfig-tsconfig.json} +5 -17
- package/models/trace/handlers/handlers.prebundle.d.ts +4 -0
- package/models/trace/handlers/handlers.prebundle.js +8 -0
- package/models/trace/handlers/handlers.prebundle.js.map +1 -0
- package/models/trace/handlers/handlers.prebundle.ts +8 -0
- package/models/trace/helpers/SamplesIntegrator.js +8 -13
- package/models/trace/helpers/SamplesIntegrator.js.map +1 -1
- package/models/trace/helpers/Trace.js +0 -7
- package/models/trace/helpers/Trace.js.map +1 -1
- package/models/trace/helpers/devtools_entrypoint-bundle-tsconfig-tsconfig.json +43 -0
- package/models/trace/helpers/helpers.prebundle.d.ts +7 -0
- package/models/trace/helpers/helpers.prebundle.js +11 -0
- package/models/trace/helpers/helpers.prebundle.js.map +1 -0
- package/models/trace/helpers/helpers.prebundle.ts +11 -0
- package/models/trace/insights/CLSCulprits.d.ts +27 -7
- package/models/trace/insights/CLSCulprits.js +34 -15
- package/models/trace/insights/CLSCulprits.js.map +1 -1
- package/models/trace/insights/Common.d.ts +1 -1
- package/models/trace/insights/Common.js +3 -3
- package/models/trace/insights/Common.js.map +1 -1
- package/models/trace/insights/DOMSize.d.ts +26 -1
- package/models/trace/insights/DOMSize.js +34 -1
- package/models/trace/insights/DOMSize.js.map +1 -1
- package/models/trace/insights/DocumentLatency.d.ts +2 -2
- package/models/trace/insights/DocumentLatency.js +3 -3
- package/models/trace/insights/DocumentLatency.js.map +1 -1
- package/models/trace/insights/ForcedReflow.d.ts +1 -1
- package/models/trace/insights/ForcedReflow.js +1 -1
- package/models/trace/insights/ForcedReflow.js.map +1 -1
- package/models/trace/insights/{InteractionToNextPaint.d.ts → INPBreakdown.d.ts} +8 -8
- package/models/trace/insights/{InteractionToNextPaint.js → INPBreakdown.js} +10 -10
- package/models/trace/insights/INPBreakdown.js.map +1 -0
- package/models/trace/insights/ImageDelivery.js +18 -7
- package/models/trace/insights/ImageDelivery.js.map +1 -1
- package/models/trace/insights/{LCPPhases.d.ts → LCPBreakdown.d.ts} +26 -22
- package/models/trace/insights/{LCPPhases.js → LCPBreakdown.js} +56 -46
- package/models/trace/insights/LCPBreakdown.js.map +1 -0
- package/models/trace/insights/LCPDiscovery.js +1 -1
- package/models/trace/insights/LCPDiscovery.js.map +1 -1
- package/models/trace/insights/Models.d.ts +2 -2
- package/models/trace/insights/Models.js +2 -2
- package/models/trace/insights/Models.js.map +1 -1
- package/models/trace/insights/NetworkDependencyTree.d.ts +34 -8
- package/models/trace/insights/NetworkDependencyTree.js +144 -18
- package/models/trace/insights/NetworkDependencyTree.js.map +1 -1
- package/models/trace/insights/Viewport.d.ts +8 -2
- package/models/trace/insights/Viewport.js +16 -1
- package/models/trace/insights/Viewport.js.map +1 -1
- package/models/trace/insights/devtools_entrypoint-bundle-tsconfig-tsconfig.json +43 -0
- package/models/trace/insights/insights-tsconfig.json +2 -2
- package/models/trace/insights/insights.prebundle.d.ts +4 -0
- package/models/trace/insights/insights.prebundle.js +8 -0
- package/models/trace/insights/insights.prebundle.js.map +1 -0
- package/models/trace/insights/insights.prebundle.ts +8 -0
- package/models/trace/insights/types.d.ts +2 -2
- package/models/trace/insights/types.js +2 -2
- package/models/trace/insights/types.js.map +1 -1
- package/models/trace/lantern/core/core.prebundle.d.ts +2 -0
- package/models/trace/lantern/core/core.prebundle.js +6 -0
- package/models/trace/lantern/core/core.prebundle.js.map +1 -0
- package/models/trace/lantern/core/core.prebundle.ts +6 -0
- package/models/trace/lantern/core/devtools_entrypoint-bundle-tsconfig-tsconfig.json +43 -0
- package/models/trace/lantern/devtools_entrypoint-bundle-tsconfig-tsconfig.json +43 -0
- package/models/trace/lantern/graph/BaseNode.d.ts +5 -2
- package/models/trace/lantern/graph/BaseNode.js +8 -5
- package/models/trace/lantern/graph/BaseNode.js.map +1 -1
- package/models/trace/lantern/graph/PageDependencyGraph.js +46 -3
- package/models/trace/lantern/graph/PageDependencyGraph.js.map +1 -1
- package/models/trace/lantern/graph/devtools_entrypoint-bundle-tsconfig-tsconfig.json +43 -0
- package/models/trace/lantern/graph/graph.prebundle.d.ts +4 -0
- package/models/trace/lantern/graph/graph.prebundle.js +8 -0
- package/models/trace/lantern/graph/graph.prebundle.js.map +1 -0
- package/models/trace/lantern/graph/graph.prebundle.ts +8 -0
- package/models/trace/lantern/lantern.prebundle.d.ts +6 -0
- package/models/trace/lantern/lantern.prebundle.js +10 -0
- package/models/trace/lantern/lantern.prebundle.js.map +1 -0
- package/models/trace/lantern/lantern.prebundle.ts +17 -0
- package/models/trace/lantern/metrics/devtools_entrypoint-bundle-tsconfig-tsconfig.json +43 -0
- package/models/trace/lantern/metrics/metrics.prebundle.d.ts +8 -0
- package/models/trace/lantern/metrics/metrics.prebundle.js +12 -0
- package/models/trace/lantern/metrics/metrics.prebundle.js.map +1 -0
- package/models/trace/lantern/metrics/metrics.prebundle.ts +12 -0
- package/models/trace/lantern/simulation/Simulator.js +1 -1
- package/models/trace/lantern/simulation/Simulator.js.map +1 -1
- package/models/trace/lantern/simulation/devtools_entrypoint-bundle-tsconfig-tsconfig.json +43 -0
- package/models/trace/lantern/simulation/simulation.prebundle.d.ts +6 -0
- package/models/trace/lantern/simulation/simulation.prebundle.js +10 -0
- package/models/trace/lantern/simulation/simulation.prebundle.js.map +1 -0
- package/models/trace/lantern/simulation/simulation.prebundle.ts +10 -0
- package/models/trace/lantern/types/devtools_entrypoint-bundle-tsconfig-tsconfig.json +43 -0
- package/models/trace/lantern/types/types.prebundle.d.ts +1 -0
- package/models/trace/lantern/types/types.prebundle.js +5 -0
- package/models/trace/lantern/types/types.prebundle.js.map +1 -0
- package/models/trace/lantern/types/types.prebundle.ts +5 -0
- package/models/trace/trace-tsconfig.json +0 -1
- package/models/trace/trace.d.ts +1 -2
- package/models/trace/trace.js +1 -2
- package/models/trace/trace.js.map +1 -1
- package/models/trace/trace.prebundle.d.ts +10 -0
- package/models/trace/trace.prebundle.js +14 -0
- package/models/trace/trace.prebundle.js.map +1 -0
- package/models/trace/trace.prebundle.ts +25 -0
- package/models/trace/types/Extensions.d.ts +6 -1
- package/models/trace/types/Extensions.js.map +1 -1
- package/models/trace/types/File.d.ts +16 -1
- 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 +7 -4
- package/models/trace/types/TraceEvents.js +4 -3
- package/models/trace/types/TraceEvents.js.map +1 -1
- package/models/trace/types/devtools_entrypoint-bundle-tsconfig-tsconfig.json +43 -0
- package/models/trace/types/types.prebundle.d.ts +5 -0
- package/models/trace/types/types.prebundle.js +9 -0
- package/models/trace/types/types.prebundle.js.map +1 -0
- package/models/trace/types/types.prebundle.ts +9 -0
- package/package.json +1 -1
- package/test/test-trace-engine.mjs +2 -2
- package/core/platform/ServerTiming.d.ts +0 -31
- package/core/platform/ServerTiming.js +0 -212
- package/core/platform/ServerTiming.js.map +0 -1
- package/models/trace/TracingManager.js.map +0 -1
- package/models/trace/extras/FetchNodes.d.ts +0 -61
- package/models/trace/extras/FetchNodes.js +0 -214
- package/models/trace/extras/FetchNodes.js.map +0 -1
- package/models/trace/extras/Metadata.d.ts +0 -3
- package/models/trace/extras/Metadata.js +0 -71
- package/models/trace/extras/Metadata.js.map +0 -1
- package/models/trace/extras/TimelineJSProfile.d.ts +0 -13
- package/models/trace/extras/TimelineJSProfile.js +0 -55
- package/models/trace/extras/TimelineJSProfile.js.map +0 -1
- package/models/trace/extras/URLForEntry.d.ts +0 -12
- package/models/trace/extras/URLForEntry.js +0 -43
- package/models/trace/extras/URLForEntry.js.map +0 -1
- package/models/trace/handlers/ServerTimingsHandler.d.ts +0 -9
- package/models/trace/handlers/ServerTimingsHandler.js +0 -106
- package/models/trace/handlers/ServerTimingsHandler.js.map +0 -1
- package/models/trace/insights/CumulativeLayoutShift.d.ts +0 -57
- package/models/trace/insights/CumulativeLayoutShift.js +0 -335
- package/models/trace/insights/CumulativeLayoutShift.js.map +0 -1
- package/models/trace/insights/InsightRunners.d.ts +0 -9
- package/models/trace/insights/InsightRunners.js +0 -13
- package/models/trace/insights/InsightRunners.js.map +0 -1
- package/models/trace/insights/InteractionToNextPaint.js.map +0 -1
- package/models/trace/insights/LCPPhases.js.map +0 -1
- package/models/trace/insights/LargestContentfulPaint.d.ts +0 -38
- package/models/trace/insights/LargestContentfulPaint.js +0 -113
- package/models/trace/insights/LargestContentfulPaint.js.map +0 -1
- package/models/trace/insights/ThirdPartyWeb.d.ts +0 -13
- package/models/trace/insights/ThirdPartyWeb.js +0 -42
- package/models/trace/insights/ThirdPartyWeb.js.map +0 -1
- package/models/trace/root-causes/LayoutShift.d.ts +0 -125
- package/models/trace/root-causes/LayoutShift.js +0 -519
- package/models/trace/root-causes/LayoutShift.js.map +0 -1
- package/models/trace/root-causes/RootCauses.d.ts +0 -15
- package/models/trace/root-causes/RootCauses.js +0 -12
- package/models/trace/root-causes/RootCauses.js.map +0 -1
- package/models/trace/root-causes/bundle-tsconfig.json +0 -1
- package/models/trace/root-causes/root-causes.d.ts +0 -1
- package/models/trace/root-causes/root-causes.js +0 -5
- package/models/trace/root-causes/root-causes.js.map +0 -1
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
// Copyright 2023 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 SDK from '../../../core/sdk/sdk.js';
|
|
5
|
-
import * as Types from '../types/types.js';
|
|
6
|
-
const domLookUpSingleNodeCache = new Map();
|
|
7
|
-
const domLookUpBatchNodesCache = new Map();
|
|
8
|
-
export function clearCacheForTesting() {
|
|
9
|
-
domLookUpSingleNodeCache.clear();
|
|
10
|
-
domLookUpBatchNodesCache.clear();
|
|
11
|
-
layoutShiftSourcesCache.clear();
|
|
12
|
-
normalizedLayoutShiftNodesCache.clear();
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Looks up the DOM Node on the page for the given BackendNodeId. Uses the
|
|
16
|
-
* provided ParsedTrace as the cache and will cache the result after the
|
|
17
|
-
* first lookup.
|
|
18
|
-
*/
|
|
19
|
-
export async function domNodeForBackendNodeID(modelData, nodeId) {
|
|
20
|
-
const fromCache = domLookUpSingleNodeCache.get(modelData)?.get(nodeId);
|
|
21
|
-
if (fromCache !== undefined) {
|
|
22
|
-
return fromCache;
|
|
23
|
-
}
|
|
24
|
-
const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
|
|
25
|
-
const domModel = target?.model(SDK.DOMModel.DOMModel);
|
|
26
|
-
if (!domModel) {
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
const domNodesMap = await domModel.pushNodesByBackendIdsToFrontend(new Set([nodeId]));
|
|
30
|
-
const result = domNodesMap?.get(nodeId) || null;
|
|
31
|
-
const cacheForModel = domLookUpSingleNodeCache.get(modelData) || new Map();
|
|
32
|
-
cacheForModel.set(nodeId, result);
|
|
33
|
-
domLookUpSingleNodeCache.set(modelData, cacheForModel);
|
|
34
|
-
return result;
|
|
35
|
-
}
|
|
36
|
-
const nodeIdsForEventCache = new WeakMap();
|
|
37
|
-
/**
|
|
38
|
-
* Extracts a set of NodeIds for a given event.
|
|
39
|
-
* NOTE: you probably don't want to call this and instead use
|
|
40
|
-
* `extractRelatedDOMNodesFromEvent`, which will fetch the nodes over CDP.
|
|
41
|
-
* This method is primarily exported so we can test the logic more easily
|
|
42
|
-
* without having to mock the CDP layer.
|
|
43
|
-
**/
|
|
44
|
-
export function nodeIdsForEvent(modelData, event) {
|
|
45
|
-
const fromCache = nodeIdsForEventCache.get(event);
|
|
46
|
-
if (fromCache) {
|
|
47
|
-
return fromCache;
|
|
48
|
-
}
|
|
49
|
-
const foundIds = new Set();
|
|
50
|
-
if (Types.Events.isLayout(event)) {
|
|
51
|
-
event.args.endData?.layoutRoots.forEach(root => foundIds.add(root.nodeId));
|
|
52
|
-
}
|
|
53
|
-
else if (Types.Events.isSyntheticLayoutShift(event) && event.args.data?.impacted_nodes) {
|
|
54
|
-
event.args.data.impacted_nodes.forEach(node => foundIds.add(node.node_id));
|
|
55
|
-
}
|
|
56
|
-
else if (Types.Events.isLargestContentfulPaintCandidate(event) && typeof event.args.data?.nodeId !== 'undefined') {
|
|
57
|
-
foundIds.add(event.args.data.nodeId);
|
|
58
|
-
}
|
|
59
|
-
else if (Types.Events.isPaint(event) && typeof event.args.data.nodeId !== 'undefined') {
|
|
60
|
-
foundIds.add(event.args.data.nodeId);
|
|
61
|
-
}
|
|
62
|
-
else if (Types.Events.isPaintImage(event) && typeof event.args.data.nodeId !== 'undefined') {
|
|
63
|
-
foundIds.add(event.args.data.nodeId);
|
|
64
|
-
}
|
|
65
|
-
else if (Types.Events.isScrollLayer(event) && typeof event.args.data.nodeId !== 'undefined') {
|
|
66
|
-
foundIds.add(event.args.data.nodeId);
|
|
67
|
-
}
|
|
68
|
-
else if (Types.Events.isSyntheticAnimation(event) && typeof event.args.data.beginEvent.args.data.nodeId !== 'undefined') {
|
|
69
|
-
foundIds.add(event.args.data.beginEvent.args.data.nodeId);
|
|
70
|
-
}
|
|
71
|
-
else if (Types.Events.isDecodeImage(event)) {
|
|
72
|
-
// For a DecodeImage event, we can use the ImagePaintingHandler, which has
|
|
73
|
-
// done the work to build the relationship between a DecodeImage event and
|
|
74
|
-
// the corresponding PaintImage event.
|
|
75
|
-
const paintImageEvent = modelData.ImagePainting.paintImageForEvent.get(event);
|
|
76
|
-
if (typeof paintImageEvent?.args.data.nodeId !== 'undefined') {
|
|
77
|
-
foundIds.add(paintImageEvent.args.data.nodeId);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
else if (Types.Events.isDrawLazyPixelRef(event) && event.args?.LazyPixelRef) {
|
|
81
|
-
const paintImageEvent = modelData.ImagePainting.paintImageByDrawLazyPixelRef.get(event.args.LazyPixelRef);
|
|
82
|
-
if (typeof paintImageEvent?.args.data.nodeId !== 'undefined') {
|
|
83
|
-
foundIds.add(paintImageEvent.args.data.nodeId);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
else if (Types.Events.isParseMetaViewport(event) && typeof event.args?.data.node_id !== 'undefined') {
|
|
87
|
-
foundIds.add(event.args.data.node_id);
|
|
88
|
-
}
|
|
89
|
-
nodeIdsForEventCache.set(event, foundIds);
|
|
90
|
-
return foundIds;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Looks up for backend node ids in different types of trace events
|
|
94
|
-
* and resolves them into related DOM nodes.
|
|
95
|
-
* This method should be progressively updated to support more events
|
|
96
|
-
* containing node ids which we want to resolve.
|
|
97
|
-
*/
|
|
98
|
-
export async function extractRelatedDOMNodesFromEvent(modelData, event) {
|
|
99
|
-
const nodeIds = nodeIdsForEvent(modelData, event);
|
|
100
|
-
if (nodeIds.size) {
|
|
101
|
-
return await domNodesForMultipleBackendNodeIds(modelData, Array.from(nodeIds));
|
|
102
|
-
}
|
|
103
|
-
return null;
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Takes a set of Protocol.DOM.BackendNodeId ids and will return a map of NodeId=>DOMNode.
|
|
107
|
-
* Results are cached based on 1) the provided ParsedTrace and 2) the provided set of IDs.
|
|
108
|
-
*/
|
|
109
|
-
export async function domNodesForMultipleBackendNodeIds(modelData, nodeIds) {
|
|
110
|
-
const fromCache = domLookUpBatchNodesCache.get(modelData)?.get(nodeIds);
|
|
111
|
-
if (fromCache) {
|
|
112
|
-
return fromCache;
|
|
113
|
-
}
|
|
114
|
-
const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
|
|
115
|
-
const domModel = target?.model(SDK.DOMModel.DOMModel);
|
|
116
|
-
if (!domModel) {
|
|
117
|
-
return new Map();
|
|
118
|
-
}
|
|
119
|
-
const domNodesMap = await domModel.pushNodesByBackendIdsToFrontend(new Set(nodeIds)) || new Map();
|
|
120
|
-
const cacheForModel = domLookUpBatchNodesCache.get(modelData) ||
|
|
121
|
-
new Map();
|
|
122
|
-
cacheForModel.set(nodeIds, domNodesMap);
|
|
123
|
-
domLookUpBatchNodesCache.set(modelData, cacheForModel);
|
|
124
|
-
return domNodesMap;
|
|
125
|
-
}
|
|
126
|
-
const layoutShiftSourcesCache = new Map();
|
|
127
|
-
const normalizedLayoutShiftNodesCache = new Map();
|
|
128
|
-
/**
|
|
129
|
-
* Calculates and returns a list of sources for a LayoutShift.
|
|
130
|
-
* Here, a source is considered as a node that moved and contributed to the
|
|
131
|
-
* given LayoutShift existing and the score it was given. Each source returned
|
|
132
|
-
* contains a reference to the DOM Node, and its dimensions (as a DOMRect), both
|
|
133
|
-
* before and now, so we can see how this node changed and how that impacted the
|
|
134
|
-
* layout shift.
|
|
135
|
-
*
|
|
136
|
-
* This data is cached based on the provided model data and the given layout
|
|
137
|
-
* shift, so it is is safe to call multiple times with the same input.
|
|
138
|
-
*/
|
|
139
|
-
export async function sourcesForLayoutShift(modelData, event) {
|
|
140
|
-
const fromCache = layoutShiftSourcesCache.get(modelData)?.get(event);
|
|
141
|
-
if (fromCache) {
|
|
142
|
-
return fromCache;
|
|
143
|
-
}
|
|
144
|
-
const impactedNodes = event.args.data?.impacted_nodes;
|
|
145
|
-
if (!impactedNodes) {
|
|
146
|
-
return [];
|
|
147
|
-
}
|
|
148
|
-
const sources = [];
|
|
149
|
-
await Promise.all(impactedNodes.map(async (node) => {
|
|
150
|
-
const domNode = await domNodeForBackendNodeID(modelData, node.node_id);
|
|
151
|
-
if (domNode) {
|
|
152
|
-
sources.push({
|
|
153
|
-
previousRect: new DOMRect(node.old_rect[0], node.old_rect[1], node.old_rect[2], node.old_rect[3]),
|
|
154
|
-
currentRect: new DOMRect(node.new_rect[0], node.new_rect[1], node.new_rect[2], node.new_rect[3]),
|
|
155
|
-
node: domNode,
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
}));
|
|
159
|
-
const cacheForModel = layoutShiftSourcesCache.get(modelData) || new Map();
|
|
160
|
-
cacheForModel.set(event, sources);
|
|
161
|
-
layoutShiftSourcesCache.set(modelData, cacheForModel);
|
|
162
|
-
return sources;
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Takes a LayoutShift and normalizes its node dimensions based on the device
|
|
166
|
-
* pixel ratio (DPR) of the user's display.
|
|
167
|
-
* This is required because the Layout Instability API is not based on CSS
|
|
168
|
-
* pixels, but physical pixels. Therefore we need to map these to normalized CSS
|
|
169
|
-
* pixels if we can. For example, if the user is on a device with a DPR of 2,
|
|
170
|
-
* the values of the node dimensions reported by the Instability API need to be
|
|
171
|
-
* divided by 2 to be accurate.
|
|
172
|
-
* This function is safe to call multiple times as results are cached based on
|
|
173
|
-
* the provided model data.
|
|
174
|
-
* See https://crbug.com/1300309 for details.
|
|
175
|
-
*/
|
|
176
|
-
export async function normalizedImpactedNodesForLayoutShift(modelData, event) {
|
|
177
|
-
const fromCache = normalizedLayoutShiftNodesCache.get(modelData)?.get(event);
|
|
178
|
-
if (fromCache) {
|
|
179
|
-
return fromCache;
|
|
180
|
-
}
|
|
181
|
-
const impactedNodes = event.args?.data?.impacted_nodes;
|
|
182
|
-
if (!impactedNodes) {
|
|
183
|
-
return [];
|
|
184
|
-
}
|
|
185
|
-
let viewportScale = null;
|
|
186
|
-
const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
|
|
187
|
-
// Get the CSS-to-physical pixel ratio of the device the inspected
|
|
188
|
-
// target is running at.
|
|
189
|
-
const evaluateResult = await target?.runtimeAgent().invoke_evaluate({ expression: 'window.devicePixelRatio' });
|
|
190
|
-
if (evaluateResult?.result.type === 'number') {
|
|
191
|
-
viewportScale = evaluateResult?.result.value ?? null;
|
|
192
|
-
}
|
|
193
|
-
if (!viewportScale) {
|
|
194
|
-
// Bail and return the nodes as is.
|
|
195
|
-
return impactedNodes;
|
|
196
|
-
}
|
|
197
|
-
const normalizedNodes = [];
|
|
198
|
-
for (const impactedNode of impactedNodes) {
|
|
199
|
-
const newNode = { ...impactedNode };
|
|
200
|
-
for (let i = 0; i < impactedNode.old_rect.length; i++) {
|
|
201
|
-
newNode.old_rect[i] /= viewportScale;
|
|
202
|
-
}
|
|
203
|
-
for (let i = 0; i < impactedNode.new_rect.length; i++) {
|
|
204
|
-
newNode.new_rect[i] /= viewportScale;
|
|
205
|
-
}
|
|
206
|
-
normalizedNodes.push(newNode);
|
|
207
|
-
}
|
|
208
|
-
const cacheForModel = normalizedLayoutShiftNodesCache.get(modelData) ||
|
|
209
|
-
new Map();
|
|
210
|
-
cacheForModel.set(event, normalizedNodes);
|
|
211
|
-
normalizedLayoutShiftNodesCache.set(modelData, cacheForModel);
|
|
212
|
-
return normalizedNodes;
|
|
213
|
-
}
|
|
214
|
-
//# sourceMappingURL=FetchNodes.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"FetchNodes.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/extras/FetchNodes.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as SDK from '../../../core/sdk/sdk.js';\nimport type * as Protocol from '../../../generated/protocol.js';\nimport type * as Handlers from '../handlers/handlers.js';\nimport * as Types from '../types/types.js';\n\nconst domLookUpSingleNodeCache =\n new Map<Handlers.Types.ParsedTrace, Map<Protocol.DOM.BackendNodeId, SDK.DOMModel.DOMNode|null>>();\nconst domLookUpBatchNodesCache = new Map<\n Handlers.Types.ParsedTrace,\n Map<Protocol.DOM.BackendNodeId[], Map<Protocol.DOM.BackendNodeId, SDK.DOMModel.DOMNode|null>>>();\n\nexport function clearCacheForTesting(): void {\n domLookUpSingleNodeCache.clear();\n domLookUpBatchNodesCache.clear();\n layoutShiftSourcesCache.clear();\n normalizedLayoutShiftNodesCache.clear();\n}\n\n/**\n * Looks up the DOM Node on the page for the given BackendNodeId. Uses the\n * provided ParsedTrace as the cache and will cache the result after the\n * first lookup.\n */\nexport async function domNodeForBackendNodeID(\n modelData: Handlers.Types.ParsedTrace, nodeId: Protocol.DOM.BackendNodeId): Promise<SDK.DOMModel.DOMNode|null> {\n const fromCache = domLookUpSingleNodeCache.get(modelData)?.get(nodeId);\n if (fromCache !== undefined) {\n return fromCache;\n }\n\n const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();\n const domModel = target?.model(SDK.DOMModel.DOMModel);\n if (!domModel) {\n return null;\n }\n\n const domNodesMap = await domModel.pushNodesByBackendIdsToFrontend(new Set([nodeId]));\n const result = domNodesMap?.get(nodeId) || null;\n\n const cacheForModel =\n domLookUpSingleNodeCache.get(modelData) || new Map<Protocol.DOM.BackendNodeId, SDK.DOMModel.DOMNode|null>();\n cacheForModel.set(nodeId, result);\n domLookUpSingleNodeCache.set(modelData, cacheForModel);\n\n return result;\n}\n\nconst nodeIdsForEventCache = new WeakMap<Types.Events.Event, Set<Protocol.DOM.BackendNodeId>>();\n/**\n * Extracts a set of NodeIds for a given event.\n * NOTE: you probably don't want to call this and instead use\n * `extractRelatedDOMNodesFromEvent`, which will fetch the nodes over CDP.\n * This method is primarily exported so we can test the logic more easily\n * without having to mock the CDP layer.\n **/\nexport function nodeIdsForEvent(\n modelData: Handlers.Types.ParsedTrace,\n event: Types.Events.Event,\n ): Set<Protocol.DOM.BackendNodeId> {\n const fromCache = nodeIdsForEventCache.get(event);\n if (fromCache) {\n return fromCache;\n }\n const foundIds = new Set<Protocol.DOM.BackendNodeId>();\n\n if (Types.Events.isLayout(event)) {\n event.args.endData?.layoutRoots.forEach(root => foundIds.add(root.nodeId));\n } else if (Types.Events.isSyntheticLayoutShift(event) && event.args.data?.impacted_nodes) {\n event.args.data.impacted_nodes.forEach(node => foundIds.add(node.node_id));\n } else if (Types.Events.isLargestContentfulPaintCandidate(event) && typeof event.args.data?.nodeId !== 'undefined') {\n foundIds.add(event.args.data.nodeId);\n } else if (Types.Events.isPaint(event) && typeof event.args.data.nodeId !== 'undefined') {\n foundIds.add(event.args.data.nodeId);\n } else if (Types.Events.isPaintImage(event) && typeof event.args.data.nodeId !== 'undefined') {\n foundIds.add(event.args.data.nodeId);\n } else if (Types.Events.isScrollLayer(event) && typeof event.args.data.nodeId !== 'undefined') {\n foundIds.add(event.args.data.nodeId);\n } else if (\n Types.Events.isSyntheticAnimation(event) && typeof event.args.data.beginEvent.args.data.nodeId !== 'undefined') {\n foundIds.add(event.args.data.beginEvent.args.data.nodeId);\n } else if (Types.Events.isDecodeImage(event)) {\n // For a DecodeImage event, we can use the ImagePaintingHandler, which has\n // done the work to build the relationship between a DecodeImage event and\n // the corresponding PaintImage event.\n const paintImageEvent = modelData.ImagePainting.paintImageForEvent.get(event);\n if (typeof paintImageEvent?.args.data.nodeId !== 'undefined') {\n foundIds.add(paintImageEvent.args.data.nodeId);\n }\n } else if (Types.Events.isDrawLazyPixelRef(event) && event.args?.LazyPixelRef) {\n const paintImageEvent = modelData.ImagePainting.paintImageByDrawLazyPixelRef.get(event.args.LazyPixelRef);\n if (typeof paintImageEvent?.args.data.nodeId !== 'undefined') {\n foundIds.add(paintImageEvent.args.data.nodeId);\n }\n } else if (Types.Events.isParseMetaViewport(event) && typeof event.args?.data.node_id !== 'undefined') {\n foundIds.add(event.args.data.node_id);\n }\n nodeIdsForEventCache.set(event, foundIds);\n return foundIds;\n}\n\n/**\n * Looks up for backend node ids in different types of trace events\n * and resolves them into related DOM nodes.\n * This method should be progressively updated to support more events\n * containing node ids which we want to resolve.\n */\nexport async function extractRelatedDOMNodesFromEvent(modelData: Handlers.Types.ParsedTrace, event: Types.Events.Event):\n Promise<Map<Protocol.DOM.BackendNodeId, SDK.DOMModel.DOMNode|null>|null> {\n const nodeIds = nodeIdsForEvent(modelData, event);\n if (nodeIds.size) {\n return await domNodesForMultipleBackendNodeIds(modelData, Array.from(nodeIds));\n }\n return null;\n}\n\n/**\n * Takes a set of Protocol.DOM.BackendNodeId ids and will return a map of NodeId=>DOMNode.\n * Results are cached based on 1) the provided ParsedTrace and 2) the provided set of IDs.\n */\nexport async function domNodesForMultipleBackendNodeIds(\n modelData: Handlers.Types.ParsedTrace,\n nodeIds: Protocol.DOM.BackendNodeId[]): Promise<Map<Protocol.DOM.BackendNodeId, SDK.DOMModel.DOMNode|null>> {\n const fromCache = domLookUpBatchNodesCache.get(modelData)?.get(nodeIds);\n if (fromCache) {\n return fromCache;\n }\n const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();\n const domModel = target?.model(SDK.DOMModel.DOMModel);\n if (!domModel) {\n return new Map();\n }\n\n const domNodesMap = await domModel.pushNodesByBackendIdsToFrontend(new Set(nodeIds)) || new Map();\n\n const cacheForModel = domLookUpBatchNodesCache.get(modelData) ||\n new Map<Protocol.DOM.BackendNodeId[], Map<Protocol.DOM.BackendNodeId, SDK.DOMModel.DOMNode|null>>();\n cacheForModel.set(nodeIds, domNodesMap);\n domLookUpBatchNodesCache.set(modelData, cacheForModel);\n\n return domNodesMap;\n}\n\nconst layoutShiftSourcesCache =\n new Map<Handlers.Types.ParsedTrace, Map<Types.Events.LayoutShift, readonly LayoutShiftSource[]>>();\n\nconst normalizedLayoutShiftNodesCache =\n new Map<Handlers.Types.ParsedTrace, Map<Types.Events.LayoutShift, readonly Types.Events.TraceImpactedNode[]>>();\n\nexport interface LayoutShiftSource {\n previousRect: DOMRect;\n currentRect: DOMRect;\n node: SDK.DOMModel.DOMNode;\n}\n\n/**\n * Calculates and returns a list of sources for a LayoutShift.\n * Here, a source is considered as a node that moved and contributed to the\n * given LayoutShift existing and the score it was given. Each source returned\n * contains a reference to the DOM Node, and its dimensions (as a DOMRect), both\n * before and now, so we can see how this node changed and how that impacted the\n * layout shift.\n *\n * This data is cached based on the provided model data and the given layout\n * shift, so it is is safe to call multiple times with the same input.\n */\nexport async function sourcesForLayoutShift(\n modelData: Handlers.Types.ParsedTrace, event: Types.Events.LayoutShift): Promise<readonly LayoutShiftSource[]> {\n const fromCache = layoutShiftSourcesCache.get(modelData)?.get(event);\n if (fromCache) {\n return fromCache;\n }\n const impactedNodes = event.args.data?.impacted_nodes;\n if (!impactedNodes) {\n return [];\n }\n const sources: LayoutShiftSource[] = [];\n await Promise.all(impactedNodes.map(async node => {\n const domNode = await domNodeForBackendNodeID(modelData, node.node_id);\n if (domNode) {\n sources.push({\n previousRect: new DOMRect(node.old_rect[0], node.old_rect[1], node.old_rect[2], node.old_rect[3]),\n currentRect: new DOMRect(node.new_rect[0], node.new_rect[1], node.new_rect[2], node.new_rect[3]),\n node: domNode,\n });\n }\n }));\n const cacheForModel =\n layoutShiftSourcesCache.get(modelData) || new Map<Types.Events.LayoutShift, LayoutShiftSource[]>();\n cacheForModel.set(event, sources);\n layoutShiftSourcesCache.set(modelData, cacheForModel);\n return sources;\n}\n\n/**\n * Takes a LayoutShift and normalizes its node dimensions based on the device\n * pixel ratio (DPR) of the user's display.\n * This is required because the Layout Instability API is not based on CSS\n * pixels, but physical pixels. Therefore we need to map these to normalized CSS\n * pixels if we can. For example, if the user is on a device with a DPR of 2,\n * the values of the node dimensions reported by the Instability API need to be\n * divided by 2 to be accurate.\n * This function is safe to call multiple times as results are cached based on\n * the provided model data.\n * See https://crbug.com/1300309 for details.\n */\nexport async function normalizedImpactedNodesForLayoutShift(\n modelData: Handlers.Types.ParsedTrace,\n event: Types.Events.LayoutShift): Promise<readonly Types.Events.TraceImpactedNode[]> {\n const fromCache = normalizedLayoutShiftNodesCache.get(modelData)?.get(event);\n if (fromCache) {\n return fromCache;\n }\n const impactedNodes = event.args?.data?.impacted_nodes;\n if (!impactedNodes) {\n return [];\n }\n\n let viewportScale: number|null = null;\n const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();\n // Get the CSS-to-physical pixel ratio of the device the inspected\n // target is running at.\n const evaluateResult = await target?.runtimeAgent().invoke_evaluate({expression: 'window.devicePixelRatio'});\n if (evaluateResult?.result.type === 'number') {\n viewportScale = evaluateResult?.result.value as number ?? null;\n }\n\n if (!viewportScale) {\n // Bail and return the nodes as is.\n return impactedNodes;\n }\n\n const normalizedNodes: Types.Events.TraceImpactedNode[] = [];\n for (const impactedNode of impactedNodes) {\n const newNode = {...impactedNode};\n for (let i = 0; i < impactedNode.old_rect.length; i++) {\n newNode.old_rect[i] /= viewportScale;\n }\n for (let i = 0; i < impactedNode.new_rect.length; i++) {\n newNode.new_rect[i] /= viewportScale;\n }\n normalizedNodes.push(newNode);\n }\n\n const cacheForModel = normalizedLayoutShiftNodesCache.get(modelData) ||\n new Map<Types.Events.LayoutShift, readonly Types.Events.TraceImpactedNode[]>();\n cacheForModel.set(event, normalizedNodes);\n normalizedLayoutShiftNodesCache.set(modelData, cacheForModel);\n\n return normalizedNodes;\n}\n"]}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
// import type * as CrUXManager from '../../crux-manager/crux-manager.js';
|
|
2
|
-
import * as Types from '../types/types.js';
|
|
3
|
-
export declare function forNewRecording(isCpuProfile: boolean, recordStartTime?: number, emulatedDeviceTitle?: string, cruxFieldData?: any[]): Promise<Types.File.MetaData>;
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
// Copyright 2023 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 SDK from '../../../core/sdk/sdk.js';
|
|
5
|
-
import * as Types from '../types/types.js';
|
|
6
|
-
export async function forNewRecording(isCpuProfile, recordStartTime, emulatedDeviceTitle, cruxFieldData) {
|
|
7
|
-
try {
|
|
8
|
-
if (isCpuProfile) {
|
|
9
|
-
// For CPU profile, only specify data origin
|
|
10
|
-
return {
|
|
11
|
-
dataOrigin: Types.File.DataOrigin.CPU_PROFILE,
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
const cpuThrottlingManager = SDK.CPUThrottlingManager.CPUThrottlingManager.instance();
|
|
15
|
-
// If the CPU Throttling manager has yet to have its primary page target
|
|
16
|
-
// set, it will block on the call to get the current hardware concurrency
|
|
17
|
-
// until it does. At this point where the user has recorded a trace, that
|
|
18
|
-
// target should have been set. So if it doesn't have it set, we instead
|
|
19
|
-
// just bail and don't store the hardware concurrency (this is only
|
|
20
|
-
// metadata, not mission critical information).
|
|
21
|
-
// We also race this call against a 1s timeout, because sometimes this call
|
|
22
|
-
// can hang (unsure exactly why) and we do not want to block parsing for
|
|
23
|
-
// too long as a result.
|
|
24
|
-
function getConcurrencyOrTimeout() {
|
|
25
|
-
return Promise.race([
|
|
26
|
-
SDK.CPUThrottlingManager.CPUThrottlingManager.instance().getHardwareConcurrency(),
|
|
27
|
-
new Promise(resolve => {
|
|
28
|
-
setTimeout(() => resolve(undefined), 1_000);
|
|
29
|
-
}),
|
|
30
|
-
]);
|
|
31
|
-
}
|
|
32
|
-
const hardwareConcurrency = cpuThrottlingManager.hasPrimaryPageTargetSet() ? await getConcurrencyOrTimeout() : undefined;
|
|
33
|
-
const cpuThrottling = SDK.CPUThrottlingManager.CPUThrottlingManager.instance().cpuThrottlingRate();
|
|
34
|
-
const networkConditions = SDK.NetworkManager.MultitargetNetworkManager.instance().isThrottling() ?
|
|
35
|
-
SDK.NetworkManager.MultitargetNetworkManager.instance().networkConditions() :
|
|
36
|
-
undefined;
|
|
37
|
-
let networkThrottlingConditions;
|
|
38
|
-
let networkTitle;
|
|
39
|
-
if (networkConditions) {
|
|
40
|
-
networkThrottlingConditions = {
|
|
41
|
-
download: networkConditions.download,
|
|
42
|
-
upload: networkConditions.upload,
|
|
43
|
-
latency: networkConditions.latency,
|
|
44
|
-
packetLoss: networkConditions.packetLoss,
|
|
45
|
-
packetQueueLength: networkConditions.packetQueueLength,
|
|
46
|
-
packetReordering: networkConditions.packetReordering,
|
|
47
|
-
targetLatency: networkConditions.targetLatency,
|
|
48
|
-
};
|
|
49
|
-
networkTitle =
|
|
50
|
-
typeof networkConditions.title === 'function' ? networkConditions.title() : networkConditions.title;
|
|
51
|
-
}
|
|
52
|
-
return {
|
|
53
|
-
source: 'DevTools',
|
|
54
|
-
startTime: recordStartTime ? new Date(recordStartTime).toJSON() : undefined, // ISO-8601 timestamp
|
|
55
|
-
emulatedDeviceTitle,
|
|
56
|
-
cpuThrottling: cpuThrottling !== 1 ? cpuThrottling : undefined,
|
|
57
|
-
networkThrottling: networkTitle,
|
|
58
|
-
networkThrottlingConditions,
|
|
59
|
-
hardwareConcurrency,
|
|
60
|
-
dataOrigin: Types.File.DataOrigin.TRACE_EVENTS,
|
|
61
|
-
cruxFieldData,
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
catch {
|
|
65
|
-
// If anything went wrong, it does not really matter. The impact is that we
|
|
66
|
-
// will not save the metadata when we save the trace to disk, but that is
|
|
67
|
-
// not really important, so just return empty object and move on
|
|
68
|
-
return {};
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
//# sourceMappingURL=Metadata.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Metadata.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/extras/Metadata.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as SDK from '../../../core/sdk/sdk.js';\nimport type * as CrUXManager from '../../crux-manager/crux-manager.js';\nimport * as Types from '../types/types.js';\n\nexport async function forNewRecording(\n isCpuProfile: boolean, recordStartTime?: number, emulatedDeviceTitle?: string,\n cruxFieldData?: CrUXManager.PageResult[]): Promise<Types.File.MetaData> {\n try {\n if (isCpuProfile) {\n // For CPU profile, only specify data origin\n return {\n dataOrigin: Types.File.DataOrigin.CPU_PROFILE,\n };\n }\n const cpuThrottlingManager = SDK.CPUThrottlingManager.CPUThrottlingManager.instance();\n\n // If the CPU Throttling manager has yet to have its primary page target\n // set, it will block on the call to get the current hardware concurrency\n // until it does. At this point where the user has recorded a trace, that\n // target should have been set. So if it doesn't have it set, we instead\n // just bail and don't store the hardware concurrency (this is only\n // metadata, not mission critical information).\n // We also race this call against a 1s timeout, because sometimes this call\n // can hang (unsure exactly why) and we do not want to block parsing for\n // too long as a result.\n function getConcurrencyOrTimeout(): Promise<number|undefined> {\n return Promise.race([\n SDK.CPUThrottlingManager.CPUThrottlingManager.instance().getHardwareConcurrency(),\n new Promise<undefined>(resolve => {\n setTimeout(() => resolve(undefined), 1_000);\n }),\n ]);\n }\n\n const hardwareConcurrency =\n cpuThrottlingManager.hasPrimaryPageTargetSet() ? await getConcurrencyOrTimeout() : undefined;\n const cpuThrottling = SDK.CPUThrottlingManager.CPUThrottlingManager.instance().cpuThrottlingRate();\n const networkConditions = SDK.NetworkManager.MultitargetNetworkManager.instance().isThrottling() ?\n SDK.NetworkManager.MultitargetNetworkManager.instance().networkConditions() :\n undefined;\n\n let networkThrottlingConditions;\n let networkTitle;\n if (networkConditions) {\n networkThrottlingConditions = {\n download: networkConditions.download,\n upload: networkConditions.upload,\n latency: networkConditions.latency,\n packetLoss: networkConditions.packetLoss,\n packetQueueLength: networkConditions.packetQueueLength,\n packetReordering: networkConditions.packetReordering,\n targetLatency: networkConditions.targetLatency,\n };\n networkTitle =\n typeof networkConditions.title === 'function' ? networkConditions.title() : networkConditions.title;\n }\n\n return {\n source: 'DevTools',\n startTime: recordStartTime ? new Date(recordStartTime).toJSON() : undefined, // ISO-8601 timestamp\n emulatedDeviceTitle,\n cpuThrottling: cpuThrottling !== 1 ? cpuThrottling : undefined,\n networkThrottling: networkTitle,\n networkThrottlingConditions,\n hardwareConcurrency,\n dataOrigin: Types.File.DataOrigin.TRACE_EVENTS,\n cruxFieldData,\n };\n } catch {\n // If anything went wrong, it does not really matter. The impact is that we\n // will not save the metadata when we save the trace to disk, but that is\n // not really important, so just return empty object and move on\n return {};\n }\n}\n"]}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type * as Protocol from '../../../generated/protocol.js';
|
|
2
|
-
import * as Types from '../types/types.js';
|
|
3
|
-
export declare class TimelineJSProfileProcessor {
|
|
4
|
-
static isNativeRuntimeFrame(frame: Protocol.Runtime.CallFrame): boolean;
|
|
5
|
-
static nativeGroup(nativeName: string): string | null;
|
|
6
|
-
static createFakeTraceFromCpuProfile(profile: Protocol.Profiler.Profile, tid: Types.Events.ThreadID): Types.Events.Event[];
|
|
7
|
-
}
|
|
8
|
-
export declare namespace TimelineJSProfileProcessor {
|
|
9
|
-
const enum NativeGroups {
|
|
10
|
-
COMPILE = "Compile",
|
|
11
|
-
PARSE = "Parse"
|
|
12
|
-
}
|
|
13
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
// Copyright 2014 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 Types from '../types/types.js';
|
|
5
|
-
// TODO(paulirish): Delete this file.
|
|
6
|
-
// - Move isNativeRuntimeFrame and nativeGroup to TraceEvents.d.ts (or TraceTree)
|
|
7
|
-
// - Move createFakeTraceFromCpuProfile to TimelineLoader
|
|
8
|
-
export class TimelineJSProfileProcessor {
|
|
9
|
-
static isNativeRuntimeFrame(frame) {
|
|
10
|
-
return frame.url === 'native V8Runtime';
|
|
11
|
-
}
|
|
12
|
-
static nativeGroup(nativeName) {
|
|
13
|
-
if (nativeName.startsWith('Parse')) {
|
|
14
|
-
return "Parse" /* TimelineJSProfileProcessor.NativeGroups.PARSE */;
|
|
15
|
-
}
|
|
16
|
-
if (nativeName.startsWith('Compile') || nativeName.startsWith('Recompile')) {
|
|
17
|
-
return "Compile" /* TimelineJSProfileProcessor.NativeGroups.COMPILE */;
|
|
18
|
-
}
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
static createFakeTraceFromCpuProfile(profile, tid) {
|
|
22
|
-
const events = [];
|
|
23
|
-
const threadName = `Thread ${tid}`;
|
|
24
|
-
appendEvent('TracingStartedInPage', { data: { sessionId: '1' } }, 0, 0, "M" /* Types.Events.Phase.METADATA */);
|
|
25
|
-
appendEvent("thread_name" /* Types.Events.Name.THREAD_NAME */, { name: threadName }, 0, 0, "M" /* Types.Events.Phase.METADATA */, '__metadata');
|
|
26
|
-
if (!profile) {
|
|
27
|
-
return events;
|
|
28
|
-
}
|
|
29
|
-
// Append a root to show the start time of the profile (which is earlier than first sample), so the Performance
|
|
30
|
-
// panel won't truncate this time period.
|
|
31
|
-
// 'JSRoot' doesn't exist in the new engine and is not the name of an actual trace event, but changing it might break other trace processing tools that rely on this, so we stick with this name.
|
|
32
|
-
// TODO(crbug.com/341234884): consider removing this or clarify why it's required.
|
|
33
|
-
appendEvent('JSRoot', {}, profile.startTime, profile.endTime - profile.startTime, "X" /* Types.Events.Phase.COMPLETE */, 'toplevel');
|
|
34
|
-
// TODO: create a `Profile` event instead, as `cpuProfile` is legacy
|
|
35
|
-
appendEvent('CpuProfile', { data: { cpuProfile: profile } }, profile.endTime, 0, "X" /* Types.Events.Phase.COMPLETE */);
|
|
36
|
-
return events;
|
|
37
|
-
function appendEvent(name, args, ts, dur, ph, cat) {
|
|
38
|
-
const event = {
|
|
39
|
-
cat: cat || 'disabled-by-default-devtools.timeline',
|
|
40
|
-
name,
|
|
41
|
-
ph: ph || "X" /* Types.Events.Phase.COMPLETE */,
|
|
42
|
-
pid: Types.Events.ProcessID(1),
|
|
43
|
-
tid,
|
|
44
|
-
ts: Types.Timing.MicroSeconds(ts),
|
|
45
|
-
args,
|
|
46
|
-
};
|
|
47
|
-
if (dur) {
|
|
48
|
-
event.dur = Types.Timing.MicroSeconds(dur);
|
|
49
|
-
}
|
|
50
|
-
events.push(event);
|
|
51
|
-
return event;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
//# sourceMappingURL=TimelineJSProfile.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TimelineJSProfile.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/extras/TimelineJSProfile.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAK7B,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAE3C,qCAAqC;AACrC,mFAAmF;AACnF,2DAA2D;AAC3D,MAAM,OAAO,0BAA0B;IACrC,MAAM,CAAC,oBAAoB,CAAC,KAAiC;QAC3D,OAAO,KAAK,CAAC,GAAG,KAAK,kBAAkB,CAAC;IAC1C,CAAC;IAED,MAAM,CAAC,WAAW,CAAC,UAAkB;QACnC,IAAI,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACnC,mEAAqD;QACvD,CAAC;QACD,IAAI,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC3E,uEAAuD;QACzD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,6BAA6B,CAAC,OAAkC,EAAE,GAA0B;QAEjG,MAAM,MAAM,GAAyB,EAAE,CAAC;QAExC,MAAM,UAAU,GAAG,UAAU,GAAG,EAAE,CAAC;QACnC,WAAW,CAAC,sBAAsB,EAAE,EAAC,IAAI,EAAE,EAAC,SAAS,EAAE,GAAG,EAAC,EAAC,EAAE,CAAC,EAAE,CAAC,wCAA8B,CAAC;QACjG,WAAW,oDAAgC,EAAC,IAAI,EAAE,UAAU,EAAC,EAAE,CAAC,EAAE,CAAC,yCAA+B,YAAY,CAAC,CAAC;QAChH,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,+GAA+G;QAC/G,yCAAyC;QACzC,iMAAiM;QACjM,kFAAkF;QAClF,WAAW,CACP,QAAQ,EAAE,EAAE,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,SAAS,yCAA+B,UAAU,CAAC,CAAC;QAEnH,oEAAoE;QACpE,WAAW,CAAC,YAAY,EAAE,EAAC,IAAI,EAAE,EAAC,UAAU,EAAE,OAAO,EAAC,EAAC,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,wCAA8B,CAAC;QAC1G,OAAO,MAAM,CAAC;QAEd,SAAS,WAAW,CAChB,IAAY,EAAE,IAAS,EAAE,EAAU,EAAE,GAAY,EAAE,EAAuB,EAAE,GAAY;YAC1F,MAAM,KAAK,GAAuB;gBAChC,GAAG,EAAE,GAAG,IAAI,uCAAuC;gBACnD,IAAI;gBACJ,EAAE,EAAE,EAAE,yCAA+B;gBACrC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;gBAC9B,GAAG;gBACH,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;gBACjC,IAAI;aACL,CAAC;YAEF,IAAI,GAAG,EAAE,CAAC;gBACR,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;YAC7C,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnB,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF","sourcesContent":["// Copyright 2014 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/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type * as Protocol from '../../../generated/protocol.js';\nimport * as Types from '../types/types.js';\n\n// TODO(paulirish): Delete this file.\n// - Move isNativeRuntimeFrame and nativeGroup to TraceEvents.d.ts (or TraceTree)\n// - Move createFakeTraceFromCpuProfile to TimelineLoader\nexport class TimelineJSProfileProcessor {\n static isNativeRuntimeFrame(frame: Protocol.Runtime.CallFrame): boolean {\n return frame.url === 'native V8Runtime';\n }\n\n static nativeGroup(nativeName: string): string|null {\n if (nativeName.startsWith('Parse')) {\n return TimelineJSProfileProcessor.NativeGroups.PARSE;\n }\n if (nativeName.startsWith('Compile') || nativeName.startsWith('Recompile')) {\n return TimelineJSProfileProcessor.NativeGroups.COMPILE;\n }\n return null;\n }\n\n static createFakeTraceFromCpuProfile(profile: Protocol.Profiler.Profile, tid: Types.Events.ThreadID):\n Types.Events.Event[] {\n const events: Types.Events.Event[] = [];\n\n const threadName = `Thread ${tid}`;\n appendEvent('TracingStartedInPage', {data: {sessionId: '1'}}, 0, 0, Types.Events.Phase.METADATA);\n appendEvent(Types.Events.Name.THREAD_NAME, {name: threadName}, 0, 0, Types.Events.Phase.METADATA, '__metadata');\n if (!profile) {\n return events;\n }\n\n // Append a root to show the start time of the profile (which is earlier than first sample), so the Performance\n // panel won't truncate this time period.\n // 'JSRoot' doesn't exist in the new engine and is not the name of an actual trace event, but changing it might break other trace processing tools that rely on this, so we stick with this name.\n // TODO(crbug.com/341234884): consider removing this or clarify why it's required.\n appendEvent(\n 'JSRoot', {}, profile.startTime, profile.endTime - profile.startTime, Types.Events.Phase.COMPLETE, 'toplevel');\n\n // TODO: create a `Profile` event instead, as `cpuProfile` is legacy\n appendEvent('CpuProfile', {data: {cpuProfile: profile}}, profile.endTime, 0, Types.Events.Phase.COMPLETE);\n return events;\n\n function appendEvent(\n name: string, args: any, ts: number, dur?: number, ph?: Types.Events.Phase, cat?: string): Types.Events.Event {\n const event: Types.Events.Event = {\n cat: cat || 'disabled-by-default-devtools.timeline',\n name,\n ph: ph || Types.Events.Phase.COMPLETE,\n pid: Types.Events.ProcessID(1),\n tid,\n ts: Types.Timing.MicroSeconds(ts),\n args,\n };\n\n if (dur) {\n event.dur = Types.Timing.MicroSeconds(dur);\n }\n events.push(event);\n return event;\n }\n }\n}\n\nexport namespace TimelineJSProfileProcessor {\n export const enum NativeGroups {\n COMPILE = 'Compile',\n PARSE = 'Parse',\n }\n}\n"]}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type * as Platform from '../../../core/platform/platform.js';
|
|
2
|
-
import type * as Handlers from '../handlers/handlers.js';
|
|
3
|
-
import * as Types from '../types/types.js';
|
|
4
|
-
/**
|
|
5
|
-
* Use this helper whenever resolving an URL's source mapping is not an
|
|
6
|
-
* option. For example when processing non-ui data. Otherwise use the
|
|
7
|
-
* helper SourceMapsResolver::resolvedURLForEntry
|
|
8
|
-
*
|
|
9
|
-
* If an URL will be displayed in the UI, it's likely you should not use
|
|
10
|
-
* this helper and prefer the other option instead.
|
|
11
|
-
*/
|
|
12
|
-
export declare function getNonResolved(parsedTrace: Handlers.Types.ParsedTrace, entry: Types.Events.Event): Platform.DevToolsPath.UrlString | null;
|
|
@@ -1,43 +0,0 @@
|
|
|
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 Types from '../types/types.js';
|
|
5
|
-
/**
|
|
6
|
-
* Use this helper whenever resolving an URL's source mapping is not an
|
|
7
|
-
* option. For example when processing non-ui data. Otherwise use the
|
|
8
|
-
* helper SourceMapsResolver::resolvedURLForEntry
|
|
9
|
-
*
|
|
10
|
-
* If an URL will be displayed in the UI, it's likely you should not use
|
|
11
|
-
* this helper and prefer the other option instead.
|
|
12
|
-
*/
|
|
13
|
-
export function getNonResolved(parsedTrace, entry) {
|
|
14
|
-
if (Types.Events.isProfileCall(entry)) {
|
|
15
|
-
return entry.callFrame.url;
|
|
16
|
-
}
|
|
17
|
-
if (entry.args?.data?.stackTrace && entry.args.data.stackTrace.length > 0) {
|
|
18
|
-
return entry.args.data.stackTrace[0].url;
|
|
19
|
-
}
|
|
20
|
-
if (Types.Events.isSyntheticNetworkRequest(entry)) {
|
|
21
|
-
return entry.args.data.url;
|
|
22
|
-
}
|
|
23
|
-
// DecodeImage events use the URL from the relevant PaintImage event.
|
|
24
|
-
if (Types.Events.isDecodeImage(entry)) {
|
|
25
|
-
const paintEvent = parsedTrace.ImagePainting.paintImageForEvent.get(entry);
|
|
26
|
-
return paintEvent ? getNonResolved(parsedTrace, paintEvent) : null;
|
|
27
|
-
}
|
|
28
|
-
// DrawLazyPixelRef events use the URL from the relevant PaintImage event.
|
|
29
|
-
if (Types.Events.isDrawLazyPixelRef(entry) && entry.args?.LazyPixelRef) {
|
|
30
|
-
const paintEvent = parsedTrace.ImagePainting.paintImageByDrawLazyPixelRef.get(entry.args.LazyPixelRef);
|
|
31
|
-
return paintEvent ? getNonResolved(parsedTrace, paintEvent) : null;
|
|
32
|
-
}
|
|
33
|
-
// ParseHTML events store the URL under beginData, not data.
|
|
34
|
-
if (Types.Events.isParseHTML(entry)) {
|
|
35
|
-
return entry.args.beginData.url;
|
|
36
|
-
}
|
|
37
|
-
// For all other events, try to see if the URL is provided, else return null.
|
|
38
|
-
if (entry.args?.data?.url) {
|
|
39
|
-
return entry.args.data.url;
|
|
40
|
-
}
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
//# sourceMappingURL=URLForEntry.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"URLForEntry.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/extras/URLForEntry.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAI7B,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAE3C;;;;;;;GAOG;AAEH,MAAM,UAAU,cAAc,CAC1B,WAAuC,EAAE,KAAyB;IACpE,IAAI,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC,SAAS,CAAC,GAAsC,CAAC;IAChE,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1E,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAsC,CAAC;IAC9E,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,CAAC,yBAAyB,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAsC,CAAC;IAChE,CAAC;IAED,qEAAqE;IACrE,IAAI,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,MAAM,UAAU,GAAG,WAAW,CAAC,aAAa,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3E,OAAO,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACrE,CAAC;IAED,0EAA0E;IAC1E,IAAI,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC;QACvE,MAAM,UAAU,GAAG,WAAW,CAAC,aAAa,CAAC,4BAA4B,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACvG,OAAO,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACrE,CAAC;IAED,4DAA4D;IAC5D,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAsC,CAAC;IACrE,CAAC;IAED,6EAA6E;IAC7E,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAsC,CAAC;IAChE,CAAC;IAED,OAAO,IAAI,CAAC;AACd,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 type * as Platform from '../../../core/platform/platform.js';\nimport type * as Handlers from '../handlers/handlers.js';\nimport * as Types from '../types/types.js';\n\n/**\n * Use this helper whenever resolving an URL's source mapping is not an\n * option. For example when processing non-ui data. Otherwise use the\n * helper SourceMapsResolver::resolvedURLForEntry\n *\n * If an URL will be displayed in the UI, it's likely you should not use\n * this helper and prefer the other option instead.\n */\n\nexport function getNonResolved(\n parsedTrace: Handlers.Types.ParsedTrace, entry: Types.Events.Event): Platform.DevToolsPath.UrlString|null {\n if (Types.Events.isProfileCall(entry)) {\n return entry.callFrame.url as Platform.DevToolsPath.UrlString;\n }\n\n if (entry.args?.data?.stackTrace && entry.args.data.stackTrace.length > 0) {\n return entry.args.data.stackTrace[0].url as Platform.DevToolsPath.UrlString;\n }\n\n if (Types.Events.isSyntheticNetworkRequest(entry)) {\n return entry.args.data.url as Platform.DevToolsPath.UrlString;\n }\n\n // DecodeImage events use the URL from the relevant PaintImage event.\n if (Types.Events.isDecodeImage(entry)) {\n const paintEvent = parsedTrace.ImagePainting.paintImageForEvent.get(entry);\n return paintEvent ? getNonResolved(parsedTrace, paintEvent) : null;\n }\n\n // DrawLazyPixelRef events use the URL from the relevant PaintImage event.\n if (Types.Events.isDrawLazyPixelRef(entry) && entry.args?.LazyPixelRef) {\n const paintEvent = parsedTrace.ImagePainting.paintImageByDrawLazyPixelRef.get(entry.args.LazyPixelRef);\n return paintEvent ? getNonResolved(parsedTrace, paintEvent) : null;\n }\n\n // ParseHTML events store the URL under beginData, not data.\n if (Types.Events.isParseHTML(entry)) {\n return entry.args.beginData.url as Platform.DevToolsPath.UrlString;\n }\n\n // For all other events, try to see if the URL is provided, else return null.\n if (entry.args?.data?.url) {\n return entry.args.data.url as Platform.DevToolsPath.UrlString;\n }\n\n return null;\n}\n"]}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import * as Types from '../types/types.js';
|
|
2
|
-
import type { HandlerName } from './types.js';
|
|
3
|
-
export declare function reset(): void;
|
|
4
|
-
export declare function handleEvent(_event: Types.Events.Event): void;
|
|
5
|
-
export declare function finalize(): Promise<void>;
|
|
6
|
-
export declare function data(): {
|
|
7
|
-
serverTimings: Types.Events.SyntheticServerTiming[];
|
|
8
|
-
};
|
|
9
|
-
export declare function deps(): HandlerName[];
|
|
@@ -1,106 +0,0 @@
|
|
|
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 Platform from '../../../core/platform/platform.js';
|
|
5
|
-
import * as Helpers from '../helpers/helpers.js';
|
|
6
|
-
import * as Types from '../types/types.js';
|
|
7
|
-
import { data as networkData } from './NetworkRequestsHandler.js';
|
|
8
|
-
const serverTimings = [];
|
|
9
|
-
export function reset() {
|
|
10
|
-
serverTimings.length = 0;
|
|
11
|
-
}
|
|
12
|
-
export function handleEvent(_event) {
|
|
13
|
-
// Implementation not needed because data is sourced from NetworkRequestsHandler
|
|
14
|
-
}
|
|
15
|
-
export async function finalize() {
|
|
16
|
-
extractServerTimings();
|
|
17
|
-
Helpers.Trace.sortTraceEventsInPlace(serverTimings);
|
|
18
|
-
}
|
|
19
|
-
const RESPONSE_START_METRIC_NAME = 'response-start';
|
|
20
|
-
const RESPONSE_END_METRIC_NAME = 'response-end';
|
|
21
|
-
/**
|
|
22
|
-
* Creates synthetic trace events based on server timings in the
|
|
23
|
-
* `Server-Timing` response header. A non-standard `start` param is
|
|
24
|
-
* expected on each metric that contains the start time of the timing
|
|
25
|
-
* based on the server clock.
|
|
26
|
-
*
|
|
27
|
-
* In order to estimate the offset between the server and client clocks,
|
|
28
|
-
* we look for the non-standard `response-start` and `response-end`
|
|
29
|
-
* metrics in the response header, which contain the start and end
|
|
30
|
-
* timestamps of the network request processing in the server. We
|
|
31
|
-
* compare these with the times the request was sent and received in the
|
|
32
|
-
* client to estimate the offset between the client and the server
|
|
33
|
-
* clocks.
|
|
34
|
-
*
|
|
35
|
-
* With this offset estimation at hand, we can map timestamps from the
|
|
36
|
-
* server clock to the tracing clock and locate the timings in the
|
|
37
|
-
* performance timeline.
|
|
38
|
-
*/
|
|
39
|
-
function extractServerTimings() {
|
|
40
|
-
for (const networkEvent of networkData().byTime) {
|
|
41
|
-
let timingsInRequest = null;
|
|
42
|
-
for (const header of networkEvent.args.data.responseHeaders) {
|
|
43
|
-
const headerName = header.name.toLocaleLowerCase();
|
|
44
|
-
// Some popular hosting providers like vercel or render get rid of
|
|
45
|
-
// Server-Timing headers added by users, so as a workaround we
|
|
46
|
-
// also support server timing headers with the `-test` suffix
|
|
47
|
-
// while this feature is experimental, to enable easier trials.
|
|
48
|
-
if (headerName === 'server-timing' || headerName === 'server-timing-test') {
|
|
49
|
-
header.name = 'server-timing';
|
|
50
|
-
timingsInRequest = Platform.ServerTiming.ServerTiming.parseHeaders([header]);
|
|
51
|
-
continue;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
const serverStart = timingsInRequest?.find(timing => timing.metric === RESPONSE_START_METRIC_NAME)?.start;
|
|
55
|
-
const serverEnd = timingsInRequest?.find(timing => timing.metric === RESPONSE_END_METRIC_NAME)?.start;
|
|
56
|
-
if (!serverStart || !serverEnd || !timingsInRequest) {
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
const serverStartInMicro = serverStart * 1_000;
|
|
60
|
-
const serverEndInMicro = serverEnd * 1_000;
|
|
61
|
-
serverTimings.push(...createSyntheticServerTiming(networkEvent, serverStartInMicro, serverEndInMicro, timingsInRequest));
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
function createSyntheticServerTiming(request, serverStart, serverEnd, timingsInRequest) {
|
|
65
|
-
const clientStart = request.args.data.syntheticData.sendStartTime;
|
|
66
|
-
const clientEndTime = request.args.data.syntheticData.sendStartTime + request.args.data.syntheticData.waiting;
|
|
67
|
-
const offset = Types.Timing.MicroSeconds((serverStart - clientStart + serverEnd - clientEndTime) / 2);
|
|
68
|
-
const convertedServerTimings = [];
|
|
69
|
-
for (const timing of timingsInRequest) {
|
|
70
|
-
if (timing.metric === RESPONSE_START_METRIC_NAME || timing.metric === RESPONSE_END_METRIC_NAME) {
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
if (timing.start === null) {
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
|
-
const convertedTimestamp = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(timing.start)) - offset;
|
|
77
|
-
const parsedUrl = new URL(request.args.data.url);
|
|
78
|
-
const origin = parsedUrl.origin;
|
|
79
|
-
const serverTiming = Helpers.SyntheticEvents.SyntheticEventsManager.registerServerTiming({
|
|
80
|
-
rawSourceEvent: request.rawSourceEvent,
|
|
81
|
-
name: timing.metric,
|
|
82
|
-
ph: "X" /* Types.Events.Phase.COMPLETE */,
|
|
83
|
-
pid: Types.Events.ProcessID(0),
|
|
84
|
-
tid: Types.Events.ThreadID(0),
|
|
85
|
-
ts: Types.Timing.MicroSeconds(convertedTimestamp),
|
|
86
|
-
dur: Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(timing.value)),
|
|
87
|
-
cat: 'devtools.server-timing',
|
|
88
|
-
args: { data: { desc: timing.description || undefined, origin } },
|
|
89
|
-
});
|
|
90
|
-
if (!request.args.data.syntheticServerTimings) {
|
|
91
|
-
request.args.data.syntheticServerTimings = [];
|
|
92
|
-
}
|
|
93
|
-
request.args.data.syntheticServerTimings.push(serverTiming);
|
|
94
|
-
convertedServerTimings.push(serverTiming);
|
|
95
|
-
}
|
|
96
|
-
return convertedServerTimings;
|
|
97
|
-
}
|
|
98
|
-
export function data() {
|
|
99
|
-
return {
|
|
100
|
-
serverTimings,
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
export function deps() {
|
|
104
|
-
return ['NetworkRequests'];
|
|
105
|
-
}
|
|
106
|
-
//# sourceMappingURL=ServerTimingsHandler.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ServerTimingsHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/ServerTimingsHandler.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 Platform from '../../../core/platform/platform.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {data as networkData} from './NetworkRequestsHandler.js';\nimport type {HandlerName} from './types.js';\n\nconst serverTimings: Types.Events.SyntheticServerTiming[] = [];\n\nexport function reset(): void {\n serverTimings.length = 0;\n}\n\nexport function handleEvent(_event: Types.Events.Event): void {\n // Implementation not needed because data is sourced from NetworkRequestsHandler\n}\n\nexport async function finalize(): Promise<void> {\n extractServerTimings();\n Helpers.Trace.sortTraceEventsInPlace(serverTimings);\n}\n\nconst RESPONSE_START_METRIC_NAME = 'response-start';\nconst RESPONSE_END_METRIC_NAME = 'response-end';\n\n/**\n * Creates synthetic trace events based on server timings in the\n * `Server-Timing` response header. A non-standard `start` param is\n * expected on each metric that contains the start time of the timing\n * based on the server clock.\n *\n * In order to estimate the offset between the server and client clocks,\n * we look for the non-standard `response-start` and `response-end`\n * metrics in the response header, which contain the start and end\n * timestamps of the network request processing in the server. We\n * compare these with the times the request was sent and received in the\n * client to estimate the offset between the client and the server\n * clocks.\n *\n * With this offset estimation at hand, we can map timestamps from the\n * server clock to the tracing clock and locate the timings in the\n * performance timeline.\n */\nfunction extractServerTimings(): void {\n for (const networkEvent of networkData().byTime) {\n let timingsInRequest: Platform.ServerTiming.ServerTiming[]|null = null;\n for (const header of networkEvent.args.data.responseHeaders) {\n const headerName = header.name.toLocaleLowerCase();\n // Some popular hosting providers like vercel or render get rid of\n // Server-Timing headers added by users, so as a workaround we\n // also support server timing headers with the `-test` suffix\n // while this feature is experimental, to enable easier trials.\n if (headerName === 'server-timing' || headerName === 'server-timing-test') {\n header.name = 'server-timing';\n timingsInRequest = Platform.ServerTiming.ServerTiming.parseHeaders([header]);\n continue;\n }\n }\n const serverStart = timingsInRequest?.find(timing => timing.metric === RESPONSE_START_METRIC_NAME)?.start;\n const serverEnd = timingsInRequest?.find(timing => timing.metric === RESPONSE_END_METRIC_NAME)?.start;\n if (!serverStart || !serverEnd || !timingsInRequest) {\n continue;\n }\n\n const serverStartInMicro = serverStart * 1_000;\n const serverEndInMicro = serverEnd * 1_000;\n serverTimings.push(\n ...createSyntheticServerTiming(networkEvent, serverStartInMicro, serverEndInMicro, timingsInRequest));\n }\n}\nfunction createSyntheticServerTiming(\n request: Types.Events.SyntheticNetworkRequest, serverStart: number, serverEnd: number,\n timingsInRequest: Platform.ServerTiming.ServerTiming[]): Types.Events.SyntheticServerTiming[] {\n const clientStart = request.args.data.syntheticData.sendStartTime;\n const clientEndTime = request.args.data.syntheticData.sendStartTime + request.args.data.syntheticData.waiting;\n const offset = Types.Timing.MicroSeconds((serverStart - clientStart + serverEnd - clientEndTime) / 2);\n const convertedServerTimings: Types.Events.SyntheticServerTiming[] = [];\n for (const timing of timingsInRequest) {\n if (timing.metric === RESPONSE_START_METRIC_NAME || timing.metric === RESPONSE_END_METRIC_NAME) {\n continue;\n }\n if (timing.start === null) {\n continue;\n }\n const convertedTimestamp =\n Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(timing.start)) - offset;\n const parsedUrl = new URL(request.args.data.url);\n const origin = parsedUrl.origin;\n\n const serverTiming = Helpers.SyntheticEvents.SyntheticEventsManager.registerServerTiming({\n rawSourceEvent: request.rawSourceEvent,\n name: timing.metric,\n ph: Types.Events.Phase.COMPLETE,\n pid: Types.Events.ProcessID(0),\n tid: Types.Events.ThreadID(0),\n ts: Types.Timing.MicroSeconds(convertedTimestamp),\n dur: Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(timing.value)),\n cat: 'devtools.server-timing',\n args: {data: {desc: timing.description || undefined, origin}},\n });\n\n if (!request.args.data.syntheticServerTimings) {\n request.args.data.syntheticServerTimings = [];\n }\n request.args.data.syntheticServerTimings.push(serverTiming);\n convertedServerTimings.push(serverTiming);\n }\n return convertedServerTimings;\n}\n\nexport function data(): {serverTimings: Types.Events.SyntheticServerTiming[]} {\n return {\n serverTimings,\n };\n}\n\nexport function deps(): HandlerName[] {\n return ['NetworkRequests'];\n}\n"]}
|