@paulirish/trace_engine 0.0.20 → 0.0.21

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.
Files changed (35) hide show
  1. package/generated/protocol.d.ts +25 -4
  2. package/models/trace/handlers/InvalidationsHandler.js +0 -9
  3. package/models/trace/handlers/InvalidationsHandler.js.map +1 -1
  4. package/models/trace/handlers/MetaHandler.js +25 -6
  5. package/models/trace/handlers/MetaHandler.js.map +1 -1
  6. package/models/trace/handlers/ModelHandlers.d.ts +1 -0
  7. package/models/trace/handlers/ModelHandlers.js +1 -0
  8. package/models/trace/handlers/ModelHandlers.js.map +1 -1
  9. package/models/trace/handlers/NetworkRequestsHandler.js +4 -0
  10. package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -1
  11. package/models/trace/handlers/SelectorStatsHandler.d.ts +9 -0
  12. package/models/trace/handlers/SelectorStatsHandler.js +28 -0
  13. package/models/trace/handlers/SelectorStatsHandler.js.map +1 -0
  14. package/models/trace/handlers/UserInteractionsHandler.d.ts +2 -0
  15. package/models/trace/handlers/UserInteractionsHandler.js +7 -0
  16. package/models/trace/handlers/UserInteractionsHandler.js.map +1 -1
  17. package/models/trace/handlers/handlers-tsconfig.json +1 -0
  18. package/models/trace/helpers/Trace.d.ts +11 -0
  19. package/models/trace/helpers/Trace.js +101 -0
  20. package/models/trace/helpers/Trace.js.map +1 -1
  21. package/models/trace/insights/InsightRunners.d.ts +1 -0
  22. package/models/trace/insights/InsightRunners.js +1 -0
  23. package/models/trace/insights/InsightRunners.js.map +1 -1
  24. package/models/trace/insights/Viewport.d.ts +5 -0
  25. package/models/trace/insights/Viewport.js +39 -0
  26. package/models/trace/insights/Viewport.js.map +1 -0
  27. package/models/trace/insights/insights-tsconfig.json +1 -0
  28. package/models/trace/insights/types.d.ts +2 -1
  29. package/models/trace/insights/types.js +1 -0
  30. package/models/trace/insights/types.js.map +1 -1
  31. package/models/trace/types/TraceEvents.d.ts +44 -13
  32. package/models/trace/types/TraceEvents.js +8 -2
  33. package/models/trace/types/TraceEvents.js.map +1 -1
  34. package/package.json +1 -1
  35. package/PAUL.readme.md +0 -5
@@ -7756,8 +7756,16 @@ export declare namespace Network {
7756
7756
  RaceNetworkAndFetchHandler = "race-network-and-fetch-handler"
7757
7757
  }
7758
7758
  interface ServiceWorkerRouterInfo {
7759
- ruleIdMatched: integer;
7760
- matchedSourceType: ServiceWorkerRouterSource;
7759
+ /**
7760
+ * ID of the rule matched. If there is a matched rule, this field will
7761
+ * be set, otherwiser no value will be set.
7762
+ */
7763
+ ruleIdMatched?: integer;
7764
+ /**
7765
+ * The router source of the matched rule. If there is a matched rule, this
7766
+ * field will be set, otherwise no value will be set.
7767
+ */
7768
+ matchedSourceType?: ServiceWorkerRouterSource;
7761
7769
  }
7762
7770
  /**
7763
7771
  * HTTP response data.
@@ -7832,7 +7840,10 @@ export declare namespace Network {
7832
7840
  */
7833
7841
  fromEarlyHints?: boolean;
7834
7842
  /**
7835
- * Information about how Service Worker Static Router was used.
7843
+ * Information about how ServiceWorker Static Router API was used. If this
7844
+ * field is set with `matchedSourceType` field, a matching rule is found.
7845
+ * If this field is set without `matchedSource`, no matching rule is found.
7846
+ * Otherwise, the API is not used.
7836
7847
  */
7837
7848
  serviceWorkerRouterInfo?: ServiceWorkerRouterInfo;
7838
7849
  /**
@@ -10545,7 +10556,6 @@ export declare namespace Page {
10545
10556
  WebPrinting = "web-printing",
10546
10557
  WebShare = "web-share",
10547
10558
  WindowManagement = "window-management",
10548
- WindowPlacement = "window-placement",
10549
10559
  XrSpatialTracking = "xr-spatial-tracking"
10550
10560
  }
10551
10561
  /**
@@ -15922,6 +15932,17 @@ export declare namespace PWA {
15922
15932
  badgeCount: integer;
15923
15933
  fileHandlers: FileHandler[];
15924
15934
  }
15935
+ interface InstallRequest {
15936
+ manifestId: string;
15937
+ /**
15938
+ * The location of the app or bundle overriding the one derived from the
15939
+ * manifestId.
15940
+ */
15941
+ installUrlOrBundleUrl?: string;
15942
+ }
15943
+ interface UninstallRequest {
15944
+ manifestId: string;
15945
+ }
15925
15946
  }
15926
15947
  /**
15927
15948
  * Debugger domain exposes JavaScript debugging capabilities. It allows setting and removing
@@ -43,15 +43,6 @@ function addInvalidationToEvent(event, invalidation) {
43
43
  invalidationsForEvent.set(event, existingInvalidations);
44
44
  }
45
45
  export function handleEvent(event) {
46
- if (Types.TraceEvents.isStyleRecalcSelectorStats(event) && lastRecalcStyleEvent) {
47
- if (!lastRecalcStyleEvent.args.selector_stats) {
48
- lastRecalcStyleEvent.args.selector_stats = event.args.selector_stats;
49
- }
50
- else {
51
- lastRecalcStyleEvent.args.selector_stats.selector_timings.push(...event.args.selector_stats?.selector_timings ?? []);
52
- }
53
- return;
54
- }
55
46
  if (Types.TraceEvents.isTraceEventUpdateLayoutTree(event)) {
56
47
  lastRecalcStyleEvent = event;
57
48
  // Associate any prior invalidations with this recalc event.
@@ -1 +1 @@
1
- {"version":3,"file":"InvalidationsHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/InvalidationsHandler.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 Types from '../types/types.js';\n\nimport {HandlerState} from './types.js';\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\nconst invalidationsForEvent = new Map<Types.TraceEvents.TraceEventData, Types.TraceEvents.SyntheticInvalidation[]>();\n\nlet lastRecalcStyleEvent: Types.TraceEvents.TraceEventUpdateLayoutTree|null = null;\n\n// Used to track paints so we track invalidations correctly per paint.\nlet hasPainted = false;\n\nconst allInvalidationTrackingEvents:\n Array<Types.TraceEvents.TraceEventScheduleStyleInvalidationTracking|\n Types.TraceEvents.TraceEventStyleRecalcInvalidationTracking|Types.TraceEvents\n .TraceEventStyleInvalidatorInvalidationTracking|Types.TraceEvents.TraceEventLayoutInvalidationTracking> =\n [];\n\nexport function reset(): void {\n handlerState = HandlerState.UNINITIALIZED;\n invalidationsForEvent.clear();\n lastRecalcStyleEvent = null;\n allInvalidationTrackingEvents.length = 0;\n hasPainted = false;\n}\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('InvalidationsHandler was not reset before being initialized');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nfunction addInvalidationToEvent(\n event: Types.TraceEvents.TraceEventData,\n invalidation: Types.TraceEvents.TraceEventScheduleStyleInvalidationTracking|\n Types.TraceEvents.TraceEventStyleRecalcInvalidationTracking|\n Types.TraceEvents.TraceEventStyleInvalidatorInvalidationTracking|\n Types.TraceEvents.TraceEventLayoutInvalidationTracking): void {\n const existingInvalidations = invalidationsForEvent.get(event) || [];\n\n const syntheticInvalidation: Types.TraceEvents.SyntheticInvalidation = {\n ...invalidation,\n name: 'SyntheticInvalidation',\n frame: invalidation.args.data.frame,\n nodeId: invalidation.args.data.nodeId,\n rawEvent: invalidation,\n };\n\n if (invalidation.args.data.nodeName) {\n syntheticInvalidation.nodeName = invalidation.args.data.nodeName;\n }\n if (invalidation.args.data.reason) {\n syntheticInvalidation.reason = invalidation.args.data.reason;\n }\n if (invalidation.args.data.stackTrace) {\n syntheticInvalidation.stackTrace = invalidation.args.data.stackTrace;\n }\n\n existingInvalidations.push(syntheticInvalidation);\n invalidationsForEvent.set(event, existingInvalidations);\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (Types.TraceEvents.isStyleRecalcSelectorStats(event) && lastRecalcStyleEvent) {\n if (!lastRecalcStyleEvent.args.selector_stats) {\n lastRecalcStyleEvent.args.selector_stats = event.args.selector_stats;\n } else {\n lastRecalcStyleEvent.args.selector_stats.selector_timings.push(\n ...event.args.selector_stats?.selector_timings ?? []);\n }\n return;\n }\n\n if (Types.TraceEvents.isTraceEventUpdateLayoutTree(event)) {\n lastRecalcStyleEvent = event;\n\n // Associate any prior invalidations with this recalc event.\n for (const invalidation of allInvalidationTrackingEvents) {\n if (Types.TraceEvents.isTraceEventLayoutInvalidationTracking(invalidation)) {\n // LayoutInvalidation events cannot be associated with a LayoutTree\n // event.\n continue;\n }\n\n const recalcFrameId = lastRecalcStyleEvent.args.beginData?.frame;\n\n if (recalcFrameId && invalidation.args.data.frame === recalcFrameId) {\n addInvalidationToEvent(event, invalidation);\n }\n }\n return;\n }\n\n if (Types.TraceEvents.isTraceEventScheduleStyleInvalidationTracking(event) ||\n Types.TraceEvents.isTraceEventStyleRecalcInvalidationTracking(event) ||\n Types.TraceEvents.isTraceEventStyleInvalidatorInvalidationTracking(event) ||\n Types.TraceEvents.isTraceEventLayoutInvalidationTracking(event)) {\n if (hasPainted) {\n // If we have painted, then we can clear out the list of all existing\n // invalidations, as we cannot associate them across frames.\n allInvalidationTrackingEvents.length = 0;\n lastRecalcStyleEvent = null;\n hasPainted = false;\n }\n\n // Style invalidation events can occur before and during recalc styles. When we get a recalc style event (aka TraceEventUpdateLayoutTree), we check and associate any prior invalidations with it.\n // But any invalidations that occur during a TraceEventUpdateLayoutTree\n // event would be reported in trace events after. So each time we get an\n // invalidation that might be due to a style recalc, we check if the\n // timings overlap and if so associate them.\n if (lastRecalcStyleEvent &&\n (Types.TraceEvents.isTraceEventScheduleStyleInvalidationTracking(event) ||\n Types.TraceEvents.isTraceEventStyleRecalcInvalidationTracking(event) ||\n Types.TraceEvents.isTraceEventStyleInvalidatorInvalidationTracking(event))) {\n const recalcEndTime = lastRecalcStyleEvent.ts + (lastRecalcStyleEvent.dur || 0);\n if (event.ts >= lastRecalcStyleEvent.ts && event.ts <= recalcEndTime &&\n lastRecalcStyleEvent.args.beginData?.frame === event.args.data.frame) {\n addInvalidationToEvent(lastRecalcStyleEvent, event);\n }\n }\n\n allInvalidationTrackingEvents.push(event);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventPaint(event)) {\n // Used to ensure that we do not create relationships across frames.\n hasPainted = true;\n return;\n }\n\n if (Types.TraceEvents.isTraceEventLayout(event)) {\n const layoutFrame = event.args.beginData.frame;\n for (const invalidation of allInvalidationTrackingEvents) {\n // The only invalidations that cause a Layout are LayoutInvalidations :)\n if (!Types.TraceEvents.isTraceEventLayoutInvalidationTracking(invalidation)) {\n continue;\n }\n\n if (invalidation.args.data.frame === layoutFrame) {\n addInvalidationToEvent(event, invalidation);\n }\n }\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('InvalidationsHandler is not initialized');\n }\n\n handlerState = HandlerState.FINALIZED;\n}\n\ninterface InvalidationsData {\n invalidationsForEvent: Map<Types.TraceEvents.TraceEventData, Types.TraceEvents.SyntheticInvalidation[]>;\n}\n\nexport function data(): InvalidationsData {\n return {\n invalidationsForEvent,\n };\n}\n"]}
1
+ {"version":3,"file":"InvalidationsHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/InvalidationsHandler.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAI3C,IAAI,YAAY,qCAA6B,CAAC;AAE9C,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAA+E,CAAC;AAErH,IAAI,oBAAoB,GAAsD,IAAI,CAAC;AAEnF,sEAAsE;AACtE,IAAI,UAAU,GAAG,KAAK,CAAC;AAEvB,MAAM,6BAA6B,GAI3B,EAAE,CAAC;AAEX,MAAM,UAAU,KAAK;IACnB,YAAY,qCAA6B,CAAC;IAC1C,qBAAqB,CAAC,KAAK,EAAE,CAAC;IAC9B,oBAAoB,GAAG,IAAI,CAAC;IAC5B,6BAA6B,CAAC,MAAM,GAAG,CAAC,CAAC;IACzC,UAAU,GAAG,KAAK,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,IAAI,YAAY,uCAA+B,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IACjF,CAAC;IAED,YAAY,mCAA2B,CAAC;AAC1C,CAAC;AAED,SAAS,sBAAsB,CAC3B,KAAuC,EACvC,YAGsD;IACxD,MAAM,qBAAqB,GAAG,qBAAqB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAErE,MAAM,qBAAqB,GAA4C;QACrE,GAAG,YAAY;QACf,IAAI,EAAE,uBAAuB;QAC7B,KAAK,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;QACnC,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM;QACrC,QAAQ,EAAE,YAAY;KACvB,CAAC;IAEF,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACpC,qBAAqB,CAAC,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;IACnE,CAAC;IACD,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAClC,qBAAqB,CAAC,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IAC/D,CAAC;IACD,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QACtC,qBAAqB,CAAC,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;IACvE,CAAC;IAED,qBAAqB,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAClD,qBAAqB,CAAC,GAAG,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAuC;IACjE,IAAI,KAAK,CAAC,WAAW,CAAC,4BAA4B,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1D,oBAAoB,GAAG,KAAK,CAAC;QAE7B,4DAA4D;QAC5D,KAAK,MAAM,YAAY,IAAI,6BAA6B,EAAE,CAAC;YACzD,IAAI,KAAK,CAAC,WAAW,CAAC,sCAAsC,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC3E,mEAAmE;gBACnE,SAAS;gBACT,SAAS;YACX,CAAC;YAED,MAAM,aAAa,GAAG,oBAAoB,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC;YAEjE,IAAI,aAAa,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,aAAa,EAAE,CAAC;gBACpE,sBAAsB,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,KAAK,CAAC,WAAW,CAAC,6CAA6C,CAAC,KAAK,CAAC;QACtE,KAAK,CAAC,WAAW,CAAC,2CAA2C,CAAC,KAAK,CAAC;QACpE,KAAK,CAAC,WAAW,CAAC,gDAAgD,CAAC,KAAK,CAAC;QACzE,KAAK,CAAC,WAAW,CAAC,sCAAsC,CAAC,KAAK,CAAC,EAAE,CAAC;QACpE,IAAI,UAAU,EAAE,CAAC;YACf,qEAAqE;YACrE,4DAA4D;YAC5D,6BAA6B,CAAC,MAAM,GAAG,CAAC,CAAC;YACzC,oBAAoB,GAAG,IAAI,CAAC;YAC5B,UAAU,GAAG,KAAK,CAAC;QACrB,CAAC;QAED,kMAAkM;QAClM,uEAAuE;QACvE,wEAAwE;QACxE,oEAAoE;QACpE,4CAA4C;QAC5C,IAAI,oBAAoB;YACpB,CAAC,KAAK,CAAC,WAAW,CAAC,6CAA6C,CAAC,KAAK,CAAC;gBACtE,KAAK,CAAC,WAAW,CAAC,2CAA2C,CAAC,KAAK,CAAC;gBACpE,KAAK,CAAC,WAAW,CAAC,gDAAgD,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAChF,MAAM,aAAa,GAAG,oBAAoB,CAAC,EAAE,GAAG,CAAC,oBAAoB,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;YAChF,IAAI,KAAK,CAAC,EAAE,IAAI,oBAAoB,CAAC,EAAE,IAAI,KAAK,CAAC,EAAE,IAAI,aAAa;gBAChE,oBAAoB,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACzE,sBAAsB,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;QAED,6BAA6B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IAED,IAAI,KAAK,CAAC,WAAW,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/C,oEAAoE;QACpE,UAAU,GAAG,IAAI,CAAC;QAClB,OAAO;IACT,CAAC;IAED,IAAI,KAAK,CAAC,WAAW,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;QAChD,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;QAC/C,KAAK,MAAM,YAAY,IAAI,6BAA6B,EAAE,CAAC;YACzD,wEAAwE;YACxE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,sCAAsC,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC5E,SAAS;YACX,CAAC;YAED,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;gBACjD,sBAAsB,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,IAAI,YAAY,qCAA6B,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,YAAY,iCAAyB,CAAC;AACxC,CAAC;AAMD,MAAM,UAAU,IAAI;IAClB,OAAO;QACL,qBAAqB;KACtB,CAAC;AACJ,CAAC","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 Types from '../types/types.js';\n\nimport {HandlerState} from './types.js';\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\nconst invalidationsForEvent = new Map<Types.TraceEvents.TraceEventData, Types.TraceEvents.SyntheticInvalidation[]>();\n\nlet lastRecalcStyleEvent: Types.TraceEvents.TraceEventUpdateLayoutTree|null = null;\n\n// Used to track paints so we track invalidations correctly per paint.\nlet hasPainted = false;\n\nconst allInvalidationTrackingEvents:\n Array<Types.TraceEvents.TraceEventScheduleStyleInvalidationTracking|\n Types.TraceEvents.TraceEventStyleRecalcInvalidationTracking|Types.TraceEvents\n .TraceEventStyleInvalidatorInvalidationTracking|Types.TraceEvents.TraceEventLayoutInvalidationTracking> =\n [];\n\nexport function reset(): void {\n handlerState = HandlerState.UNINITIALIZED;\n invalidationsForEvent.clear();\n lastRecalcStyleEvent = null;\n allInvalidationTrackingEvents.length = 0;\n hasPainted = false;\n}\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('InvalidationsHandler was not reset before being initialized');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nfunction addInvalidationToEvent(\n event: Types.TraceEvents.TraceEventData,\n invalidation: Types.TraceEvents.TraceEventScheduleStyleInvalidationTracking|\n Types.TraceEvents.TraceEventStyleRecalcInvalidationTracking|\n Types.TraceEvents.TraceEventStyleInvalidatorInvalidationTracking|\n Types.TraceEvents.TraceEventLayoutInvalidationTracking): void {\n const existingInvalidations = invalidationsForEvent.get(event) || [];\n\n const syntheticInvalidation: Types.TraceEvents.SyntheticInvalidation = {\n ...invalidation,\n name: 'SyntheticInvalidation',\n frame: invalidation.args.data.frame,\n nodeId: invalidation.args.data.nodeId,\n rawEvent: invalidation,\n };\n\n if (invalidation.args.data.nodeName) {\n syntheticInvalidation.nodeName = invalidation.args.data.nodeName;\n }\n if (invalidation.args.data.reason) {\n syntheticInvalidation.reason = invalidation.args.data.reason;\n }\n if (invalidation.args.data.stackTrace) {\n syntheticInvalidation.stackTrace = invalidation.args.data.stackTrace;\n }\n\n existingInvalidations.push(syntheticInvalidation);\n invalidationsForEvent.set(event, existingInvalidations);\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (Types.TraceEvents.isTraceEventUpdateLayoutTree(event)) {\n lastRecalcStyleEvent = event;\n\n // Associate any prior invalidations with this recalc event.\n for (const invalidation of allInvalidationTrackingEvents) {\n if (Types.TraceEvents.isTraceEventLayoutInvalidationTracking(invalidation)) {\n // LayoutInvalidation events cannot be associated with a LayoutTree\n // event.\n continue;\n }\n\n const recalcFrameId = lastRecalcStyleEvent.args.beginData?.frame;\n\n if (recalcFrameId && invalidation.args.data.frame === recalcFrameId) {\n addInvalidationToEvent(event, invalidation);\n }\n }\n return;\n }\n\n if (Types.TraceEvents.isTraceEventScheduleStyleInvalidationTracking(event) ||\n Types.TraceEvents.isTraceEventStyleRecalcInvalidationTracking(event) ||\n Types.TraceEvents.isTraceEventStyleInvalidatorInvalidationTracking(event) ||\n Types.TraceEvents.isTraceEventLayoutInvalidationTracking(event)) {\n if (hasPainted) {\n // If we have painted, then we can clear out the list of all existing\n // invalidations, as we cannot associate them across frames.\n allInvalidationTrackingEvents.length = 0;\n lastRecalcStyleEvent = null;\n hasPainted = false;\n }\n\n // Style invalidation events can occur before and during recalc styles. When we get a recalc style event (aka TraceEventUpdateLayoutTree), we check and associate any prior invalidations with it.\n // But any invalidations that occur during a TraceEventUpdateLayoutTree\n // event would be reported in trace events after. So each time we get an\n // invalidation that might be due to a style recalc, we check if the\n // timings overlap and if so associate them.\n if (lastRecalcStyleEvent &&\n (Types.TraceEvents.isTraceEventScheduleStyleInvalidationTracking(event) ||\n Types.TraceEvents.isTraceEventStyleRecalcInvalidationTracking(event) ||\n Types.TraceEvents.isTraceEventStyleInvalidatorInvalidationTracking(event))) {\n const recalcEndTime = lastRecalcStyleEvent.ts + (lastRecalcStyleEvent.dur || 0);\n if (event.ts >= lastRecalcStyleEvent.ts && event.ts <= recalcEndTime &&\n lastRecalcStyleEvent.args.beginData?.frame === event.args.data.frame) {\n addInvalidationToEvent(lastRecalcStyleEvent, event);\n }\n }\n\n allInvalidationTrackingEvents.push(event);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventPaint(event)) {\n // Used to ensure that we do not create relationships across frames.\n hasPainted = true;\n return;\n }\n\n if (Types.TraceEvents.isTraceEventLayout(event)) {\n const layoutFrame = event.args.beginData.frame;\n for (const invalidation of allInvalidationTrackingEvents) {\n // The only invalidations that cause a Layout are LayoutInvalidations :)\n if (!Types.TraceEvents.isTraceEventLayoutInvalidationTracking(invalidation)) {\n continue;\n }\n\n if (invalidation.args.data.frame === layoutFrame) {\n addInvalidationToEvent(event, invalidation);\n }\n }\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('InvalidationsHandler is not initialized');\n }\n\n handlerState = HandlerState.FINALIZED;\n}\n\ninterface InvalidationsData {\n invalidationsForEvent: Map<Types.TraceEvents.TraceEventData, Types.TraceEvents.SyntheticInvalidation[]>;\n}\n\nexport function data(): InvalidationsData {\n return {\n invalidationsForEvent,\n };\n}\n"]}
@@ -171,14 +171,33 @@ export function handleEvent(event) {
171
171
  }
172
172
  for (const frame of (event.args.data.frames ?? [])) {
173
173
  updateRendererProcessByFrame(event, frame);
174
- if (frame.parent) {
175
- continue;
174
+ if (!frame.parent) {
175
+ topLevelRendererIds.add(frame.processId);
176
+ }
177
+ // isOutermostMainFrame was added to trace events in April 2024
178
+ // [crrev.com/c/5424783].
179
+ // If our trace has that, it is the most accurate way of determining the
180
+ // main frame, as only one frame will have it set to true.
181
+ const canUseIsOutermostToDetermineMainFrame = 'isOutermostMainFrame' in frame;
182
+ if (canUseIsOutermostToDetermineMainFrame) {
183
+ // We have a "new" trace with isOutermostMainFrame. Therefore we mark
184
+ // the frame as the main frame if and ONLY IF it has
185
+ // isOutermostMainFrame set to true.
186
+ if (frame.isOutermostMainFrame) {
187
+ mainFrameId = frame.frame;
188
+ mainFrameURL = frame.url;
189
+ }
176
190
  }
177
- if (frame.url) {
178
- mainFrameId = frame.frame;
179
- mainFrameURL = frame.url;
191
+ else {
192
+ // We have an "old" trace without isOutermostMainFrame.
193
+ // We fallback to looking for frames without a parent, and that have a
194
+ // URL set. This is a crude but pretty reliable way to determine the
195
+ // main frame.
196
+ if (!frame.parent && frame.url) {
197
+ mainFrameId = frame.frame;
198
+ mainFrameURL = frame.url;
199
+ }
180
200
  }
181
- topLevelRendererIds.add(frame.processId);
182
201
  }
183
202
  return;
184
203
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MetaHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/MetaHandler.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,QAAQ,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,OAAO,MAAM,uBAAuB,CAAC;AACjD,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAI3C,qFAAqF;AACrF,MAAM,0BAA0B,GAAqB,IAAI,GAAG,EAAE,CAAC;AAE/D,4EAA4E;AAC5E,0DAA0D;AAC1D,IAAI,WAAW,GAAW,EAAE,CAAC;AAC7B,IAAI,YAAY,GAAW,EAAE,CAAC;AAE9B,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAA0E,CAAC;AAE5G,6EAA6E;AAC7E,gDAAgD;AAChD,IAAI,gBAAgB,GAAgC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AACpF,IAAI,eAAe,GAA+B,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AACjF,IAAI,YAAY,GAAgC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAChF,IAAI,WAAW,GAA+B,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7E,IAAI,YAAY,GAAiB,IAAI,CAAC;AAEtC,MAAM,YAAY,GAA8E,IAAI,GAAG,EAAE,CAAC;AAE1G,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAA+B,CAAC;AACnE,MAAM,WAAW,GAAyC;IACxD,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,iBAAiB,CAAC;IACxD,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,iBAAiB,CAAC;IACxD,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,iBAAiB,CAAC;CAC3D,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAyD,CAAC;AAC9F,MAAM,yBAAyB,GAAG,IAAI,GAAG,EAAuD,CAAC;AACjG,MAAM,oBAAoB,GAAkD,EAAE,CAAC;AAE/E,6FAA6F;AAC7F,8FAA8F;AAC9F,MAAM,gBAAgB,GAClB,IAAI,GAAG,EAAwG,CAAC;AAEpH,IAAI,uCAAuC,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5E,MAAM,mCAAmC,GAAG,IAAI,GAAG,CAAC;;;;;CAKnD,CAAC,CAAC;AAEH,IAAI,YAAY,qCAA6B,CAAC;AAC9C,gIAAgI;AAChI,6EAA6E;AAC7E,yBAAyB;AACzB,4BAA4B;AAC5B,8BAA8B;AAC9B,sEAAsE;AACtE,IAAI,cAAc,GAAG,IAAI,CAAC;AAC1B,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC;;;;CAKvC,CAAC,CAAC;AAEH,MAAM,UAAU,KAAK;IACnB,oBAAoB,CAAC,KAAK,EAAE,CAAC;IAC7B,yBAAyB,CAAC,KAAK,EAAE,CAAC;IAClC,YAAY,CAAC,KAAK,EAAE,CAAC;IACrB,oBAAoB,CAAC,MAAM,GAAG,CAAC,CAAC;IAEhC,gBAAgB,GAAG,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,eAAe,GAAG,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,YAAY,GAAG,IAAI,CAAC;IACpB,mBAAmB,CAAC,KAAK,EAAE,CAAC;IAC5B,gBAAgB,CAAC,KAAK,EAAE,CAAC;IACzB,0BAA0B,CAAC,KAAK,EAAE,CAAC;IACnC,iBAAiB,CAAC,KAAK,EAAE,CAAC;IAE1B,WAAW,CAAC,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IACtE,WAAW,CAAC,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IACtE,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IACxE,uCAAuC,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAExE,cAAc,GAAG,IAAI,CAAC;IAEtB,YAAY,qCAA6B,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,IAAI,YAAY,uCAA+B,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IAED,YAAY,mCAA2B,CAAC;AAC1C,CAAC;AAED,SAAS,4BAA4B,CACjC,KAAuC,EAAE,KAAmC;IAC9E,MAAM,mBAAmB,GAAG,QAAQ,CAAC,YAAY,CAAC,cAAc,CAAC,iBAAiB,EAAE,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IACtH,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAE5C,MAAM,sBAAsB,GAAG,QAAQ,CAAC,YAAY,CAAC,cAAc,CAC/D,0BAA0B,EAAE,KAAK,CAAC,KAAK,EACvC,GAAG,EAAE,CAAC,IAAI,GAAG,EAE+E,CAAC,CAAC;IAClG,MAAM,mBAAmB,GAAG,QAAQ,CAAC,YAAY,CAAC,cAAc,CAAC,sBAAsB,EAAE,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE;QAC7G,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;IACH,MAAM,eAAe,GAAG,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAEnD,iEAAiE;IACjE,yBAAyB;IACzB,IAAI,eAAe,IAAI,eAAe,CAAC,KAAK,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,EAAE,CAAC;QAC/D,OAAO;IACT,CAAC;IACD,6EAA6E;IAC7E,uEAAuE;IACvE,mBAAmB,CAAC,IAAI,CAAC;QACvB,KAAK;QACL,MAAM,EAAE;YACN,GAAG,EAAE,KAAK,CAAC,EAAE;YACb,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;YACjC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;SACpC;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAuC;IACjE,IAAI,YAAY,qCAA6B,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,cAAc,IAAI,uBAAuB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAwC,CAAC,EAAE,CAAC;QAClG,cAAc,GAAG,KAAK,CAAC;IACzB,CAAC;IAED,IAAI,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3C,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACrC,CAAC;IAED,8EAA8E;IAC9E,2EAA2E;IAC3E,+EAA+E;IAC/E,4EAA4E;IAC5E,qDAAqD;IACrD,IAAI,KAAK,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,mCAAmC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;QACzG,WAAW,CAAC,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;QACjF,MAAM,aAAa,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChE,WAAW,CAAC,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,aAAa,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IACnG,CAAC;IAED,IAAI,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,KAAK,CAAC;QACtC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,iBAAiB,CAAC,EAAE,CAAC;QAC7E,gBAAgB,GAAG,KAAK,CAAC,GAAG,CAAC;QAC7B,OAAO;IACT,CAAC;IAED,IAAI,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,aAAa,CAAC,EAAE,CAAC;QAC/G,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC;QACzB,OAAO;IACT,CAAC;IAED,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC7E,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC;QACxB,OAAO;IACT,CAAC;IAED,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;QACjF,eAAe,GAAG,KAAK,CAAC,GAAG,CAAC;IAC9B,CAAC;IAED,IAAI,KAAK,CAAC,WAAW,CAAC,6BAA6B,CAAC,KAAK,CAAC,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QACpF,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;QAClD,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,aAAa,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,cAAc,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QACtC,YAAY,GAAG,IAAI,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,CAAC,CAAC;IAClF,CAAC;IAED,0EAA0E;IAC1E,6EAA6E;IAC7E,uCAAuC;IACvC,IAAI,KAAK,CAAC,WAAW,CAAC,mCAAmC,CAAC,KAAK,CAAC,EAAE,CAAC;QACjE,uCAAuC,GAAG,KAAK,CAAC,EAAE,CAAC;QAEnD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;YACnD,4BAA4B,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAE3C,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBACjB,SAAS;YACX,CAAC;YAED,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;gBACd,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC;gBAC1B,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC;YAC3B,CAAC;YACD,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO;IACT,CAAC;IAED,sEAAsE;IACtE,wEAAwE;IACxE,wEAAwE;IACxE,oEAAoE;IACpE,IAAI,KAAK,CAAC,WAAW,CAAC,mCAAmC,CAAC,KAAK,CAAC,EAAE,CAAC;QACjE,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QAED,4BAA4B,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAE3C,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QAED,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACzC,OAAO;IACT,CAAC;IAED,IAAI,KAAK,CAAC,WAAW,CAAC,sBAAsB,CAAC,KAAK,CAAC,EAAE,CAAC;QACpD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAClC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QAED,MAAM,EAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAC,GAAG,SAAS,CAAC;QACrC,4BAA4B,CAAC,KAAK,EAAE,EAAC,SAAS,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAC,CAAC,CAAC;QAC9E,OAAO;IACT,CAAC;IAED,uDAAuD;IACvD,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1C,MAAM,OAAO,GAAG,QAAQ,CAAC,YAAY,CAAC,cAAc,CAAC,gBAAgB,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;QACnG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC9B,OAAO;IACT,CAAC;IAED,8EAA8E;IAC9E,6EAA6E;IAC7E,gEAAgE;IAChE,8CAA8C;IAC9C,4CAA4C;IAC5C,IAAI,KAAK,CAAC,WAAW,CAAC,kCAAkC,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACnF,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;QAClD,IAAI,yBAAyB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YAChD,wFAAwF;YACxF,yDAAyD;YACzD,qGAAqG;YACrG,mGAAmG;YACnG,OAAO;QACT,CAAC;QACD,yBAAyB,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QAEnD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;QACjC,MAAM,wBAAwB,GAAG,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACzE,wBAAwB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,oBAAoB,CAAC,GAAG,CAAC,OAAO,EAAE,wBAAwB,CAAC,CAAC;QAC5D,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;YAC5B,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QACD,OAAO;IACT,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,IAAI,YAAY,qCAA6B,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IAED,wEAAwE;IACxE,0DAA0D;IAC1D,4DAA4D;IAC5D,2EAA2E;IAC3E,2EAA2E;IAC3E,IAAI,uCAAuC,IAAI,CAAC,EAAE,CAAC;QACjD,WAAW,CAAC,GAAG,GAAG,uCAAuC,CAAC;IAC5D,CAAC;IACD,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAEjF,uEAAuE;IACvE,yEAAyE;IACzE,6EAA6E;IAC7E,yEAAyE;IACzE,uEAAuE;IACvE,WAAW;IACX,KAAK,MAAM,CAAC,EAAE,cAAc,CAAC,IAAI,0BAA0B,EAAE,CAAC;QAC5D,MAAM,mBAAmB,GAAG,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAChE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,mBAAmB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpD,MAAM,aAAa,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;YAC7C,MAAM,UAAU,GAAG,mBAAmB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAE9C,8DAA8D;YAC9D,wFAAwF;YACxF,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,aAAa,CAAC,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;gBACtE,aAAa,CAAC,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACrG,CAAC;iBAAM,CAAC;gBACN,aAAa,CAAC,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;gBAChF,aAAa,CAAC,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC9G,CAAC;QACH,CAAC;IACH,CAAC;IAED,iFAAiF;IACjF,0FAA0F;IAC1F,iDAAiD;IACjD,KAAK,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,IAAI,oBAAoB,EAAE,CAAC;QAC1D,sEAAsE;QACtE,wFAAwF;QACxF,+DAA+D;QAC/D,IAAI,0BAA0B,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5C,SAAS;QACX,CAAC;QACD,oBAAoB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACrC,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACrC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC1B,SAAS;YACX,CAAC;YACD,yBAAyB,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,uEAAuE;IACvE,6EAA6E;IAC7E,2EAA2E;IAC3E,6EAA6E;IAC7E,qEAAqE;IACrE,+CAA+C;IAC/C,2EAA2E;IAC3E,4EAA4E;IAC5E,sEAAsE;IACtE,aAAa;IACb,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9F,IAAI,iBAAiB,EAAE,CAAC;QACtB,MAAM,2BAA2B,GAAG,iBAAiB,CAAC,EAAE,GAAG,WAAW,CAAC,GAAG,GAAG,qBAAqB,CAAC;QACnG,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,EAAE,oBAAoB,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB;YACnG,2BAA2B,EAAE,CAAC;YAChC,YAAY,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,YAAY,iCAAyB,CAAC;AACxC,CAAC;AAmDD,MAAM,UAAU,IAAI;IAClB,IAAI,YAAY,mCAA2B,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IAED,OAAO;QACL,WAAW,EAAE,EAAC,GAAG,WAAW,EAAC;QAC7B,gBAAgB;QAChB,eAAe;QACf,YAAY;QACZ,YAAY;QACZ,WAAW,EAAE,WAAW,KAAK,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW;QACrF,YAAY,EAAE,YAAY,IAAI,SAAS;QACvC,WAAW;QACX,YAAY;QACZ,oBAAoB;QACpB,yBAAyB;QACzB,gBAAgB;QAChB,wBAAwB,EAAE,0BAA0B;QACpD,mBAAmB;QACnB,gBAAgB,EAAE,iBAAiB;QACnC,oBAAoB;QACpB,cAAc;KACf,CAAC;AACJ,CAAC","sourcesContent":["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {HandlerState} from './types.js';\n\n// We track the renderer processes we see in each frame on the way through the trace.\nconst rendererProcessesByFrameId: FrameProcessData = new Map();\n\n// We will often want to key data by Frame IDs, and commonly we'll care most\n// about the main frame's ID, so we store and expose that.\nlet mainFrameId: string = '';\nlet mainFrameURL: string = '';\n\nconst framesByProcessId = new Map<Types.TraceEvents.ProcessID, Map<string, Types.TraceEvents.TraceFrame>>();\n\n// We will often want to key data by the browser process, GPU process and top\n// level renderer IDs, so keep a track on those.\nlet browserProcessId: Types.TraceEvents.ProcessID = Types.TraceEvents.ProcessID(-1);\nlet browserThreadId: Types.TraceEvents.ThreadID = Types.TraceEvents.ThreadID(-1);\nlet gpuProcessId: Types.TraceEvents.ProcessID = Types.TraceEvents.ProcessID(-1);\nlet gpuThreadId: Types.TraceEvents.ThreadID = Types.TraceEvents.ThreadID(-1);\nlet viewportRect: DOMRect|null = null;\n\nconst processNames: Map<Types.TraceEvents.ProcessID, Types.TraceEvents.TraceEventProcessName> = new Map();\n\nconst topLevelRendererIds = new Set<Types.TraceEvents.ProcessID>();\nconst traceBounds: Types.Timing.TraceWindowMicroSeconds = {\n min: Types.Timing.MicroSeconds(Number.POSITIVE_INFINITY),\n max: Types.Timing.MicroSeconds(Number.NEGATIVE_INFINITY),\n range: Types.Timing.MicroSeconds(Number.POSITIVE_INFINITY),\n};\n\n/**\n * These represent the user navigating. Values such as First Contentful Paint,\n * etc, are relative to the navigation.\n *\n * We store navigation events both by the frame and navigation ID. This means\n * when we need to look them up, we can use whichever ID we have.\n *\n * Note that these Maps will have the same values in them; these are just keyed\n * differently to make look-ups easier.\n *\n * We also additionally maintain an array of only navigations that occured on\n * the main frame. In many places in the UI we only care about highlighting\n * main frame navigations, so calculating this list here is better than\n * filtering either of the below maps over and over again at the UI layer.\n */\nconst navigationsByFrameId = new Map<string, Types.TraceEvents.TraceEventNavigationStart[]>();\nconst navigationsByNavigationId = new Map<string, Types.TraceEvents.TraceEventNavigationStart>();\nconst mainFrameNavigations: Types.TraceEvents.TraceEventNavigationStart[] = [];\n\n// Represents all the threads in the trace, organized by process. This is mostly for internal\n// bookkeeping so that during the finalize pass we can obtain the main and browser thread IDs.\nconst threadsInProcess =\n new Map<Types.TraceEvents.ProcessID, Map<Types.TraceEvents.ThreadID, Types.TraceEvents.TraceEventThreadName>>();\n\nlet traceStartedTimeFromTracingStartedEvent = Types.Timing.MicroSeconds(-1);\nconst eventPhasesOfInterestForTraceBounds = new Set([\n Types.TraceEvents.Phase.BEGIN,\n Types.TraceEvents.Phase.END,\n Types.TraceEvents.Phase.COMPLETE,\n Types.TraceEvents.Phase.INSTANT,\n]);\n\nlet handlerState = HandlerState.UNINITIALIZED;\n// Tracks if the trace is a generic trace, which here means that it did not come from athe DevTools Performance Panel recording.\n// We assume a trace is generic, and mark it as not generic if we see any of:\n// - TracingStartedInPage\n// - TracingStartedInBrowser\n// - TracingSessionIdForWorker\n// These are all events which indicate this is a Chrome browser trace.\nlet traceIsGeneric = true;\nconst CHROME_WEB_TRACE_EVENTS = new Set([\n Types.TraceEvents.KnownEventName.TracingStartedInPage,\n Types.TraceEvents.KnownEventName.TracingSessionIdForWorker,\n Types.TraceEvents.KnownEventName.TracingStartedInBrowser,\n\n]);\n\nexport function reset(): void {\n navigationsByFrameId.clear();\n navigationsByNavigationId.clear();\n processNames.clear();\n mainFrameNavigations.length = 0;\n\n browserProcessId = Types.TraceEvents.ProcessID(-1);\n browserThreadId = Types.TraceEvents.ThreadID(-1);\n gpuProcessId = Types.TraceEvents.ProcessID(-1);\n gpuThreadId = Types.TraceEvents.ThreadID(-1);\n viewportRect = null;\n topLevelRendererIds.clear();\n threadsInProcess.clear();\n rendererProcessesByFrameId.clear();\n framesByProcessId.clear();\n\n traceBounds.min = Types.Timing.MicroSeconds(Number.POSITIVE_INFINITY);\n traceBounds.max = Types.Timing.MicroSeconds(Number.NEGATIVE_INFINITY);\n traceBounds.range = Types.Timing.MicroSeconds(Number.POSITIVE_INFINITY);\n traceStartedTimeFromTracingStartedEvent = Types.Timing.MicroSeconds(-1);\n\n traceIsGeneric = true;\n\n handlerState = HandlerState.UNINITIALIZED;\n}\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('Meta Handler was not reset');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nfunction updateRendererProcessByFrame(\n event: Types.TraceEvents.TraceEventData, frame: Types.TraceEvents.TraceFrame): void {\n const framesInProcessById = Platform.MapUtilities.getWithDefault(framesByProcessId, frame.processId, () => new Map());\n framesInProcessById.set(frame.frame, frame);\n\n const rendererProcessInFrame = Platform.MapUtilities.getWithDefault(\n rendererProcessesByFrameId, frame.frame,\n () => new Map<\n Types.TraceEvents.ProcessID,\n {frame: Types.TraceEvents.TraceFrame, window: Types.Timing.TraceWindowMicroSeconds}[]>());\n const rendererProcessInfo = Platform.MapUtilities.getWithDefault(rendererProcessInFrame, frame.processId, () => {\n return [];\n });\n const lastProcessData = rendererProcessInfo.at(-1);\n\n // Only store a new entry if the URL changed, otherwise it's just\n // redundant information.\n if (lastProcessData && lastProcessData.frame.url === frame.url) {\n return;\n }\n // For now we store the time of the event as the min. In the finalize we step\n // through each of these windows and update their max and range values.\n rendererProcessInfo.push({\n frame,\n window: {\n min: event.ts,\n max: Types.Timing.MicroSeconds(0),\n range: Types.Timing.MicroSeconds(0),\n },\n });\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Meta Handler is not initialized');\n }\n\n if (traceIsGeneric && CHROME_WEB_TRACE_EVENTS.has(event.name as Types.TraceEvents.KnownEventName)) {\n traceIsGeneric = false;\n }\n\n if (Types.TraceEvents.isProcessName(event)) {\n processNames.set(event.pid, event);\n }\n\n // If there is a timestamp (which meta events do not have), and the event does\n // not end with ::UMA then it, and the event is in the set of valid phases,\n // then it should be included for the purposes of calculating the trace bounds.\n // The UMA events in particular seem to be reported on page unloading, which\n // often extends the bounds of the trace unhelpfully.\n if (event.ts !== 0 && !event.name.endsWith('::UMA') && eventPhasesOfInterestForTraceBounds.has(event.ph)) {\n traceBounds.min = Types.Timing.MicroSeconds(Math.min(event.ts, traceBounds.min));\n const eventDuration = event.dur || Types.Timing.MicroSeconds(0);\n traceBounds.max = Types.Timing.MicroSeconds(Math.max(event.ts + eventDuration, traceBounds.max));\n }\n\n if (Types.TraceEvents.isProcessName(event) &&\n (event.args.name === 'Browser' || event.args.name === 'HeadlessBrowser')) {\n browserProcessId = event.pid;\n return;\n }\n\n if (Types.TraceEvents.isProcessName(event) && (event.args.name === 'Gpu' || event.args.name === 'GPU Process')) {\n gpuProcessId = event.pid;\n return;\n }\n\n if (Types.TraceEvents.isThreadName(event) && event.args.name === 'CrGpuMain') {\n gpuThreadId = event.tid;\n return;\n }\n\n if (Types.TraceEvents.isThreadName(event) && event.args.name === 'CrBrowserMain') {\n browserThreadId = event.tid;\n }\n\n if (Types.TraceEvents.isTraceEventMainFrameViewport(event) && viewportRect === null) {\n const rectAsArray = event.args.data.viewport_rect;\n const viewportX = rectAsArray[0];\n const viewportY = rectAsArray[1];\n const viewportWidth = rectAsArray[2];\n const viewportHeight = rectAsArray[5];\n viewportRect = new DOMRect(viewportX, viewportY, viewportWidth, viewportHeight);\n }\n\n // The TracingStartedInBrowser event includes the data on which frames are\n // in scope at the start of the trace. We use this to identify the frame with\n // no parent, i.e. the top level frame.\n if (Types.TraceEvents.isTraceEventTracingStartedInBrowser(event)) {\n traceStartedTimeFromTracingStartedEvent = event.ts;\n\n if (!event.args.data) {\n throw new Error('No frames found in trace data');\n }\n\n for (const frame of (event.args.data.frames ?? [])) {\n updateRendererProcessByFrame(event, frame);\n\n if (frame.parent) {\n continue;\n }\n\n if (frame.url) {\n mainFrameId = frame.frame;\n mainFrameURL = frame.url;\n }\n topLevelRendererIds.add(frame.processId);\n }\n return;\n }\n\n // FrameCommittedInBrowser events tell us information about each frame\n // and we use these to track how long each individual renderer is active\n // for. We track all renderers here (top level and those in frames), but\n // for convenience we also populate a set of top level renderer IDs.\n if (Types.TraceEvents.isTraceEventFrameCommittedInBrowser(event)) {\n const frame = event.args.data;\n if (!frame) {\n return;\n }\n\n updateRendererProcessByFrame(event, frame);\n\n if (frame.parent) {\n return;\n }\n\n topLevelRendererIds.add(frame.processId);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventCommitLoad(event)) {\n const frameData = event.args.data;\n if (!frameData) {\n return;\n }\n\n const {frame, name, url} = frameData;\n updateRendererProcessByFrame(event, {processId: event.pid, frame, name, url});\n return;\n }\n\n // Track all threads based on the process & thread IDs.\n if (Types.TraceEvents.isThreadName(event)) {\n const threads = Platform.MapUtilities.getWithDefault(threadsInProcess, event.pid, () => new Map());\n threads.set(event.tid, event);\n return;\n }\n\n // Track all navigation events. Note that there can be navigation start events\n // but where the documentLoaderURL is empty. As far as the trace rendering is\n // concerned, these events are noise so we filter them out here.\n // (The filtering of empty URLs is done in the\n // isTraceEventNavigationStartWithURL check)\n if (Types.TraceEvents.isTraceEventNavigationStartWithURL(event) && event.args.data) {\n const navigationId = event.args.data.navigationId;\n if (navigationsByNavigationId.has(navigationId)) {\n // We have only ever seen this situation once, in crbug.com/1503982, where the user ran:\n // window.location.href = 'javascript:console.log(\"foo\")'\n // In this situation two identical navigationStart events are emitted with the same data, URL and ID.\n // So, in this situation we drop/ignore any subsequent navigations if we have already seen that ID.\n return;\n }\n navigationsByNavigationId.set(navigationId, event);\n\n const frameId = event.args.frame;\n const existingFrameNavigations = navigationsByFrameId.get(frameId) || [];\n existingFrameNavigations.push(event);\n navigationsByFrameId.set(frameId, existingFrameNavigations);\n if (frameId === mainFrameId) {\n mainFrameNavigations.push(event);\n }\n return;\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Handler is not initialized');\n }\n\n // We try to set the minimum time by finding the event with the smallest\n // timestamp. However, if we also got a timestamp from the\n // TracingStartedInBrowser event, we should always use that.\n // But in some traces (for example, CPU profiles) we do not get that event,\n // hence why we need to check we got a timestamp from it before setting it.\n if (traceStartedTimeFromTracingStartedEvent >= 0) {\n traceBounds.min = traceStartedTimeFromTracingStartedEvent;\n }\n traceBounds.range = Types.Timing.MicroSeconds(traceBounds.max - traceBounds.min);\n\n // If we go from foo.com to example.com we will get a new renderer, and\n // therefore the \"top level renderer\" will have a different PID as it has\n // changed. Here we step through each renderer process and updated its window\n // bounds, such that we end up with the time ranges in the trace for when\n // each particular renderer started and stopped being the main renderer\n // process.\n for (const [, processWindows] of rendererProcessesByFrameId) {\n const processWindowValues = [...processWindows.values()].flat();\n for (let i = 0; i < processWindowValues.length; i++) {\n const currentWindow = processWindowValues[i];\n const nextWindow = processWindowValues[i + 1];\n\n // For the last window we set its max to be positive infinity.\n // TODO: Move the trace bounds handler into meta so we can clamp first and last windows.\n if (!nextWindow) {\n currentWindow.window.max = Types.Timing.MicroSeconds(traceBounds.max);\n currentWindow.window.range = Types.Timing.MicroSeconds(traceBounds.max - currentWindow.window.min);\n } else {\n currentWindow.window.max = Types.Timing.MicroSeconds(nextWindow.window.min - 1);\n currentWindow.window.range = Types.Timing.MicroSeconds(currentWindow.window.max - currentWindow.window.min);\n }\n }\n }\n\n // Frame ids which we didn't register using either the TracingStartedInBrowser or\n // the FrameCommittedInBrowser events are considered noise, so we filter them out, as well\n // as the navigations that belong to such frames.\n for (const [frameId, navigations] of navigationsByFrameId) {\n // The frames in the rendererProcessesByFrameId map come only from the\n // TracingStartedInBrowser and FrameCommittedInBrowser events, so we can use it as point\n // of comparison to determine if a frameId should be discarded.\n if (rendererProcessesByFrameId.has(frameId)) {\n continue;\n }\n navigationsByFrameId.delete(frameId);\n for (const navigation of navigations) {\n if (!navigation.args.data) {\n continue;\n }\n navigationsByNavigationId.delete(navigation.args.data.navigationId);\n }\n }\n\n // Sometimes in traces the TracingStartedInBrowser event can give us an\n // incorrect initial URL for the main frame's URL - about:blank or the URL of\n // the previous page. This doesn't matter too much except we often use this\n // URL as the visual name of the trace shown to the user (e.g. in the history\n // dropdown). We can be more accurate by finding the first main frame\n // navigaton, and using its URL, if we have it.\n // However, to avoid doing this in a case where the first navigation is far\n // into the trace's lifecycle, we only do this in situations where the first\n // navigation happened very soon (0.5 seconds) after the trace started\n // recording.\n const firstMainFrameNav = mainFrameNavigations.at(0);\n const firstNavTimeThreshold = Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(0.5));\n if (firstMainFrameNav) {\n const navigationIsWithinThreshold = firstMainFrameNav.ts - traceBounds.min < firstNavTimeThreshold;\n if (firstMainFrameNav.args.data?.isOutermostMainFrame && firstMainFrameNav.args.data?.documentLoaderURL &&\n navigationIsWithinThreshold) {\n mainFrameURL = firstMainFrameNav.args.data.documentLoaderURL;\n }\n }\n\n handlerState = HandlerState.FINALIZED;\n}\n\nexport type MetaHandlerData = {\n traceIsGeneric: boolean,\n traceBounds: Types.Timing.TraceWindowMicroSeconds,\n browserProcessId: Types.TraceEvents.ProcessID,\n processNames: Map<Types.TraceEvents.ProcessID, Types.TraceEvents.TraceEventProcessName>,\n browserThreadId: Types.TraceEvents.ThreadID,\n gpuProcessId: Types.TraceEvents.ProcessID,\n gpuThreadId?: Types.TraceEvents.ThreadID,\n viewportRect?: DOMRect,\n navigationsByFrameId: Map<string, Types.TraceEvents.TraceEventNavigationStart[]>,\n navigationsByNavigationId: Map<string, Types.TraceEvents.TraceEventNavigationStart>,\n threadsInProcess:\n Map<Types.TraceEvents.ProcessID,\n Map<Types.TraceEvents.ThreadID, Types.TraceEvents.TraceEventThreadName>>,\n mainFrameId: string,\n mainFrameURL: string,\n /**\n * A frame can have multiple renderer processes, at the same time,\n * a renderer process can have multiple URLs. This map tracks the\n * processes active on a given frame, with the time window in which\n * they were active. Because a renderer process might have multiple\n * URLs, each process in each frame has an array of windows, with an\n * entry for each URL it had.\n */\n rendererProcessesByFrame: FrameProcessData,\n topLevelRendererIds: Set<Types.TraceEvents.ProcessID>,\n frameByProcessId: Map<Types.TraceEvents.ProcessID, Map<string, Types.TraceEvents.TraceFrame>>,\n mainFrameNavigations: Types.TraceEvents.TraceEventNavigationStart[],\n};\n\n// Each frame has a single render process at a given time but it can have\n// multiple render processes during a trace, for example if a navigation\n// occurred in the frame. This map tracks the process that was active for\n// each frame at each point in time. Also, because a process can be\n// assigned to multiple URLs, there is a window for each URL a process\n// was assigned.\n//\n// Note that different sites always end up in different render\n// processes, however two different URLs can point to the same site.\n// For example: https://google.com and https://maps.google.com point to\n// the same site.\n// Read more about this in\n// https://developer.chrome.com/articles/renderingng-architecture/#threads\n// and https://web.dev/same-site-same-origin/\nexport type FrameProcessData =\n Map<string,\n Map<Types.TraceEvents.ProcessID,\n {frame: Types.TraceEvents.TraceFrame, window: Types.Timing.TraceWindowMicroSeconds}[]>>;\n\nexport function data(): MetaHandlerData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('Meta Handler is not finalized');\n }\n\n return {\n traceBounds: {...traceBounds},\n browserProcessId,\n browserThreadId,\n processNames,\n gpuProcessId,\n gpuThreadId: gpuThreadId === Types.TraceEvents.ThreadID(-1) ? undefined : gpuThreadId,\n viewportRect: viewportRect || undefined,\n mainFrameId,\n mainFrameURL,\n navigationsByFrameId,\n navigationsByNavigationId,\n threadsInProcess,\n rendererProcessesByFrame: rendererProcessesByFrameId,\n topLevelRendererIds,\n frameByProcessId: framesByProcessId,\n mainFrameNavigations,\n traceIsGeneric,\n };\n}\n"]}
1
+ {"version":3,"file":"MetaHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/MetaHandler.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {HandlerState} from './types.js';\n\n// We track the renderer processes we see in each frame on the way through the trace.\nconst rendererProcessesByFrameId: FrameProcessData = new Map();\n\n// We will often want to key data by Frame IDs, and commonly we'll care most\n// about the main frame's ID, so we store and expose that.\nlet mainFrameId: string = '';\nlet mainFrameURL: string = '';\n\nconst framesByProcessId = new Map<Types.TraceEvents.ProcessID, Map<string, Types.TraceEvents.TraceFrame>>();\n\n// We will often want to key data by the browser process, GPU process and top\n// level renderer IDs, so keep a track on those.\nlet browserProcessId: Types.TraceEvents.ProcessID = Types.TraceEvents.ProcessID(-1);\nlet browserThreadId: Types.TraceEvents.ThreadID = Types.TraceEvents.ThreadID(-1);\nlet gpuProcessId: Types.TraceEvents.ProcessID = Types.TraceEvents.ProcessID(-1);\nlet gpuThreadId: Types.TraceEvents.ThreadID = Types.TraceEvents.ThreadID(-1);\nlet viewportRect: DOMRect|null = null;\n\nconst processNames: Map<Types.TraceEvents.ProcessID, Types.TraceEvents.TraceEventProcessName> = new Map();\n\nconst topLevelRendererIds = new Set<Types.TraceEvents.ProcessID>();\nconst traceBounds: Types.Timing.TraceWindowMicroSeconds = {\n min: Types.Timing.MicroSeconds(Number.POSITIVE_INFINITY),\n max: Types.Timing.MicroSeconds(Number.NEGATIVE_INFINITY),\n range: Types.Timing.MicroSeconds(Number.POSITIVE_INFINITY),\n};\n\n/**\n * These represent the user navigating. Values such as First Contentful Paint,\n * etc, are relative to the navigation.\n *\n * We store navigation events both by the frame and navigation ID. This means\n * when we need to look them up, we can use whichever ID we have.\n *\n * Note that these Maps will have the same values in them; these are just keyed\n * differently to make look-ups easier.\n *\n * We also additionally maintain an array of only navigations that occured on\n * the main frame. In many places in the UI we only care about highlighting\n * main frame navigations, so calculating this list here is better than\n * filtering either of the below maps over and over again at the UI layer.\n */\nconst navigationsByFrameId = new Map<string, Types.TraceEvents.TraceEventNavigationStart[]>();\nconst navigationsByNavigationId = new Map<string, Types.TraceEvents.TraceEventNavigationStart>();\nconst mainFrameNavigations: Types.TraceEvents.TraceEventNavigationStart[] = [];\n\n// Represents all the threads in the trace, organized by process. This is mostly for internal\n// bookkeeping so that during the finalize pass we can obtain the main and browser thread IDs.\nconst threadsInProcess =\n new Map<Types.TraceEvents.ProcessID, Map<Types.TraceEvents.ThreadID, Types.TraceEvents.TraceEventThreadName>>();\n\nlet traceStartedTimeFromTracingStartedEvent = Types.Timing.MicroSeconds(-1);\nconst eventPhasesOfInterestForTraceBounds = new Set([\n Types.TraceEvents.Phase.BEGIN,\n Types.TraceEvents.Phase.END,\n Types.TraceEvents.Phase.COMPLETE,\n Types.TraceEvents.Phase.INSTANT,\n]);\n\nlet handlerState = HandlerState.UNINITIALIZED;\n// Tracks if the trace is a generic trace, which here means that it did not come from athe DevTools Performance Panel recording.\n// We assume a trace is generic, and mark it as not generic if we see any of:\n// - TracingStartedInPage\n// - TracingStartedInBrowser\n// - TracingSessionIdForWorker\n// These are all events which indicate this is a Chrome browser trace.\nlet traceIsGeneric = true;\nconst CHROME_WEB_TRACE_EVENTS = new Set([\n Types.TraceEvents.KnownEventName.TracingStartedInPage,\n Types.TraceEvents.KnownEventName.TracingSessionIdForWorker,\n Types.TraceEvents.KnownEventName.TracingStartedInBrowser,\n\n]);\n\nexport function reset(): void {\n navigationsByFrameId.clear();\n navigationsByNavigationId.clear();\n processNames.clear();\n mainFrameNavigations.length = 0;\n\n browserProcessId = Types.TraceEvents.ProcessID(-1);\n browserThreadId = Types.TraceEvents.ThreadID(-1);\n gpuProcessId = Types.TraceEvents.ProcessID(-1);\n gpuThreadId = Types.TraceEvents.ThreadID(-1);\n viewportRect = null;\n topLevelRendererIds.clear();\n threadsInProcess.clear();\n rendererProcessesByFrameId.clear();\n framesByProcessId.clear();\n\n traceBounds.min = Types.Timing.MicroSeconds(Number.POSITIVE_INFINITY);\n traceBounds.max = Types.Timing.MicroSeconds(Number.NEGATIVE_INFINITY);\n traceBounds.range = Types.Timing.MicroSeconds(Number.POSITIVE_INFINITY);\n traceStartedTimeFromTracingStartedEvent = Types.Timing.MicroSeconds(-1);\n\n traceIsGeneric = true;\n\n handlerState = HandlerState.UNINITIALIZED;\n}\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('Meta Handler was not reset');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nfunction updateRendererProcessByFrame(\n event: Types.TraceEvents.TraceEventData, frame: Types.TraceEvents.TraceFrame): void {\n const framesInProcessById = Platform.MapUtilities.getWithDefault(framesByProcessId, frame.processId, () => new Map());\n framesInProcessById.set(frame.frame, frame);\n\n const rendererProcessInFrame = Platform.MapUtilities.getWithDefault(\n rendererProcessesByFrameId, frame.frame,\n () => new Map<\n Types.TraceEvents.ProcessID,\n {frame: Types.TraceEvents.TraceFrame, window: Types.Timing.TraceWindowMicroSeconds}[]>());\n const rendererProcessInfo = Platform.MapUtilities.getWithDefault(rendererProcessInFrame, frame.processId, () => {\n return [];\n });\n const lastProcessData = rendererProcessInfo.at(-1);\n\n // Only store a new entry if the URL changed, otherwise it's just\n // redundant information.\n if (lastProcessData && lastProcessData.frame.url === frame.url) {\n return;\n }\n // For now we store the time of the event as the min. In the finalize we step\n // through each of these windows and update their max and range values.\n rendererProcessInfo.push({\n frame,\n window: {\n min: event.ts,\n max: Types.Timing.MicroSeconds(0),\n range: Types.Timing.MicroSeconds(0),\n },\n });\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Meta Handler is not initialized');\n }\n\n if (traceIsGeneric && CHROME_WEB_TRACE_EVENTS.has(event.name as Types.TraceEvents.KnownEventName)) {\n traceIsGeneric = false;\n }\n\n if (Types.TraceEvents.isProcessName(event)) {\n processNames.set(event.pid, event);\n }\n\n // If there is a timestamp (which meta events do not have), and the event does\n // not end with ::UMA then it, and the event is in the set of valid phases,\n // then it should be included for the purposes of calculating the trace bounds.\n // The UMA events in particular seem to be reported on page unloading, which\n // often extends the bounds of the trace unhelpfully.\n if (event.ts !== 0 && !event.name.endsWith('::UMA') && eventPhasesOfInterestForTraceBounds.has(event.ph)) {\n traceBounds.min = Types.Timing.MicroSeconds(Math.min(event.ts, traceBounds.min));\n const eventDuration = event.dur || Types.Timing.MicroSeconds(0);\n traceBounds.max = Types.Timing.MicroSeconds(Math.max(event.ts + eventDuration, traceBounds.max));\n }\n\n if (Types.TraceEvents.isProcessName(event) &&\n (event.args.name === 'Browser' || event.args.name === 'HeadlessBrowser')) {\n browserProcessId = event.pid;\n return;\n }\n\n if (Types.TraceEvents.isProcessName(event) && (event.args.name === 'Gpu' || event.args.name === 'GPU Process')) {\n gpuProcessId = event.pid;\n return;\n }\n\n if (Types.TraceEvents.isThreadName(event) && event.args.name === 'CrGpuMain') {\n gpuThreadId = event.tid;\n return;\n }\n\n if (Types.TraceEvents.isThreadName(event) && event.args.name === 'CrBrowserMain') {\n browserThreadId = event.tid;\n }\n\n if (Types.TraceEvents.isTraceEventMainFrameViewport(event) && viewportRect === null) {\n const rectAsArray = event.args.data.viewport_rect;\n const viewportX = rectAsArray[0];\n const viewportY = rectAsArray[1];\n const viewportWidth = rectAsArray[2];\n const viewportHeight = rectAsArray[5];\n viewportRect = new DOMRect(viewportX, viewportY, viewportWidth, viewportHeight);\n }\n\n // The TracingStartedInBrowser event includes the data on which frames are\n // in scope at the start of the trace. We use this to identify the frame with\n // no parent, i.e. the top level frame.\n if (Types.TraceEvents.isTraceEventTracingStartedInBrowser(event)) {\n traceStartedTimeFromTracingStartedEvent = event.ts;\n\n if (!event.args.data) {\n throw new Error('No frames found in trace data');\n }\n\n for (const frame of (event.args.data.frames ?? [])) {\n updateRendererProcessByFrame(event, frame);\n\n if (!frame.parent) {\n topLevelRendererIds.add(frame.processId);\n }\n\n // isOutermostMainFrame was added to trace events in April 2024\n // [crrev.com/c/5424783].\n // If our trace has that, it is the most accurate way of determining the\n // main frame, as only one frame will have it set to true.\n const canUseIsOutermostToDetermineMainFrame = 'isOutermostMainFrame' in frame;\n if (canUseIsOutermostToDetermineMainFrame) {\n // We have a \"new\" trace with isOutermostMainFrame. Therefore we mark\n // the frame as the main frame if and ONLY IF it has\n // isOutermostMainFrame set to true.\n if (frame.isOutermostMainFrame) {\n mainFrameId = frame.frame;\n mainFrameURL = frame.url;\n }\n } else {\n // We have an \"old\" trace without isOutermostMainFrame.\n // We fallback to looking for frames without a parent, and that have a\n // URL set. This is a crude but pretty reliable way to determine the\n // main frame.\n if (!frame.parent && frame.url) {\n mainFrameId = frame.frame;\n mainFrameURL = frame.url;\n }\n }\n }\n\n return;\n }\n\n // FrameCommittedInBrowser events tell us information about each frame\n // and we use these to track how long each individual renderer is active\n // for. We track all renderers here (top level and those in frames), but\n // for convenience we also populate a set of top level renderer IDs.\n if (Types.TraceEvents.isTraceEventFrameCommittedInBrowser(event)) {\n const frame = event.args.data;\n if (!frame) {\n return;\n }\n\n updateRendererProcessByFrame(event, frame);\n\n if (frame.parent) {\n return;\n }\n\n topLevelRendererIds.add(frame.processId);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventCommitLoad(event)) {\n const frameData = event.args.data;\n if (!frameData) {\n return;\n }\n\n const {frame, name, url} = frameData;\n updateRendererProcessByFrame(event, {processId: event.pid, frame, name, url});\n return;\n }\n\n // Track all threads based on the process & thread IDs.\n if (Types.TraceEvents.isThreadName(event)) {\n const threads = Platform.MapUtilities.getWithDefault(threadsInProcess, event.pid, () => new Map());\n threads.set(event.tid, event);\n return;\n }\n\n // Track all navigation events. Note that there can be navigation start events\n // but where the documentLoaderURL is empty. As far as the trace rendering is\n // concerned, these events are noise so we filter them out here.\n // (The filtering of empty URLs is done in the\n // isTraceEventNavigationStartWithURL check)\n if (Types.TraceEvents.isTraceEventNavigationStartWithURL(event) && event.args.data) {\n const navigationId = event.args.data.navigationId;\n if (navigationsByNavigationId.has(navigationId)) {\n // We have only ever seen this situation once, in crbug.com/1503982, where the user ran:\n // window.location.href = 'javascript:console.log(\"foo\")'\n // In this situation two identical navigationStart events are emitted with the same data, URL and ID.\n // So, in this situation we drop/ignore any subsequent navigations if we have already seen that ID.\n return;\n }\n navigationsByNavigationId.set(navigationId, event);\n\n const frameId = event.args.frame;\n const existingFrameNavigations = navigationsByFrameId.get(frameId) || [];\n existingFrameNavigations.push(event);\n navigationsByFrameId.set(frameId, existingFrameNavigations);\n if (frameId === mainFrameId) {\n mainFrameNavigations.push(event);\n }\n return;\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Handler is not initialized');\n }\n\n // We try to set the minimum time by finding the event with the smallest\n // timestamp. However, if we also got a timestamp from the\n // TracingStartedInBrowser event, we should always use that.\n // But in some traces (for example, CPU profiles) we do not get that event,\n // hence why we need to check we got a timestamp from it before setting it.\n if (traceStartedTimeFromTracingStartedEvent >= 0) {\n traceBounds.min = traceStartedTimeFromTracingStartedEvent;\n }\n traceBounds.range = Types.Timing.MicroSeconds(traceBounds.max - traceBounds.min);\n\n // If we go from foo.com to example.com we will get a new renderer, and\n // therefore the \"top level renderer\" will have a different PID as it has\n // changed. Here we step through each renderer process and updated its window\n // bounds, such that we end up with the time ranges in the trace for when\n // each particular renderer started and stopped being the main renderer\n // process.\n for (const [, processWindows] of rendererProcessesByFrameId) {\n const processWindowValues = [...processWindows.values()].flat();\n for (let i = 0; i < processWindowValues.length; i++) {\n const currentWindow = processWindowValues[i];\n const nextWindow = processWindowValues[i + 1];\n\n // For the last window we set its max to be positive infinity.\n // TODO: Move the trace bounds handler into meta so we can clamp first and last windows.\n if (!nextWindow) {\n currentWindow.window.max = Types.Timing.MicroSeconds(traceBounds.max);\n currentWindow.window.range = Types.Timing.MicroSeconds(traceBounds.max - currentWindow.window.min);\n } else {\n currentWindow.window.max = Types.Timing.MicroSeconds(nextWindow.window.min - 1);\n currentWindow.window.range = Types.Timing.MicroSeconds(currentWindow.window.max - currentWindow.window.min);\n }\n }\n }\n\n // Frame ids which we didn't register using either the TracingStartedInBrowser or\n // the FrameCommittedInBrowser events are considered noise, so we filter them out, as well\n // as the navigations that belong to such frames.\n for (const [frameId, navigations] of navigationsByFrameId) {\n // The frames in the rendererProcessesByFrameId map come only from the\n // TracingStartedInBrowser and FrameCommittedInBrowser events, so we can use it as point\n // of comparison to determine if a frameId should be discarded.\n if (rendererProcessesByFrameId.has(frameId)) {\n continue;\n }\n navigationsByFrameId.delete(frameId);\n for (const navigation of navigations) {\n if (!navigation.args.data) {\n continue;\n }\n navigationsByNavigationId.delete(navigation.args.data.navigationId);\n }\n }\n\n // Sometimes in traces the TracingStartedInBrowser event can give us an\n // incorrect initial URL for the main frame's URL - about:blank or the URL of\n // the previous page. This doesn't matter too much except we often use this\n // URL as the visual name of the trace shown to the user (e.g. in the history\n // dropdown). We can be more accurate by finding the first main frame\n // navigaton, and using its URL, if we have it.\n // However, to avoid doing this in a case where the first navigation is far\n // into the trace's lifecycle, we only do this in situations where the first\n // navigation happened very soon (0.5 seconds) after the trace started\n // recording.\n const firstMainFrameNav = mainFrameNavigations.at(0);\n const firstNavTimeThreshold = Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(0.5));\n if (firstMainFrameNav) {\n const navigationIsWithinThreshold = firstMainFrameNav.ts - traceBounds.min < firstNavTimeThreshold;\n if (firstMainFrameNav.args.data?.isOutermostMainFrame && firstMainFrameNav.args.data?.documentLoaderURL &&\n navigationIsWithinThreshold) {\n mainFrameURL = firstMainFrameNav.args.data.documentLoaderURL;\n }\n }\n\n handlerState = HandlerState.FINALIZED;\n}\n\nexport type MetaHandlerData = {\n traceIsGeneric: boolean,\n traceBounds: Types.Timing.TraceWindowMicroSeconds,\n browserProcessId: Types.TraceEvents.ProcessID,\n processNames: Map<Types.TraceEvents.ProcessID, Types.TraceEvents.TraceEventProcessName>,\n browserThreadId: Types.TraceEvents.ThreadID,\n gpuProcessId: Types.TraceEvents.ProcessID,\n gpuThreadId?: Types.TraceEvents.ThreadID,\n viewportRect?: DOMRect,\n navigationsByFrameId: Map<string, Types.TraceEvents.TraceEventNavigationStart[]>,\n navigationsByNavigationId: Map<string, Types.TraceEvents.TraceEventNavigationStart>,\n threadsInProcess:\n Map<Types.TraceEvents.ProcessID,\n Map<Types.TraceEvents.ThreadID, Types.TraceEvents.TraceEventThreadName>>,\n mainFrameId: string,\n mainFrameURL: string,\n /**\n * A frame can have multiple renderer processes, at the same time,\n * a renderer process can have multiple URLs. This map tracks the\n * processes active on a given frame, with the time window in which\n * they were active. Because a renderer process might have multiple\n * URLs, each process in each frame has an array of windows, with an\n * entry for each URL it had.\n */\n rendererProcessesByFrame: FrameProcessData,\n topLevelRendererIds: Set<Types.TraceEvents.ProcessID>,\n frameByProcessId: Map<Types.TraceEvents.ProcessID, Map<string, Types.TraceEvents.TraceFrame>>,\n mainFrameNavigations: Types.TraceEvents.TraceEventNavigationStart[],\n};\n\n// Each frame has a single render process at a given time but it can have\n// multiple render processes during a trace, for example if a navigation\n// occurred in the frame. This map tracks the process that was active for\n// each frame at each point in time. Also, because a process can be\n// assigned to multiple URLs, there is a window for each URL a process\n// was assigned.\n//\n// Note that different sites always end up in different render\n// processes, however two different URLs can point to the same site.\n// For example: https://google.com and https://maps.google.com point to\n// the same site.\n// Read more about this in\n// https://developer.chrome.com/articles/renderingng-architecture/#threads\n// and https://web.dev/same-site-same-origin/\nexport type FrameProcessData =\n Map<string,\n Map<Types.TraceEvents.ProcessID,\n {frame: Types.TraceEvents.TraceFrame, window: Types.Timing.TraceWindowMicroSeconds}[]>>;\n\nexport function data(): MetaHandlerData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('Meta Handler is not finalized');\n }\n\n return {\n traceBounds: {...traceBounds},\n browserProcessId,\n browserThreadId,\n processNames,\n gpuProcessId,\n gpuThreadId: gpuThreadId === Types.TraceEvents.ThreadID(-1) ? undefined : gpuThreadId,\n viewportRect: viewportRect || undefined,\n mainFrameId,\n mainFrameURL,\n navigationsByFrameId,\n navigationsByNavigationId,\n threadsInProcess,\n rendererProcessesByFrame: rendererProcessesByFrameId,\n topLevelRendererIds,\n frameByProcessId: framesByProcessId,\n mainFrameNavigations,\n traceIsGeneric,\n };\n}\n"]}
@@ -18,6 +18,7 @@ export * as PageLoadMetrics from './PageLoadMetricsHandler.js';
18
18
  export * as Renderer from './RendererHandler.js';
19
19
  export * as Samples from './SamplesHandler.js';
20
20
  export * as Screenshots from './ScreenshotsHandler.js';
21
+ export * as SelectorStats from './SelectorStatsHandler.js';
21
22
  export * as UserInteractions from './UserInteractionsHandler.js';
22
23
  export * as UserTimings from './UserTimingsHandler.js';
23
24
  export * as Warnings from './WarningsHandler.js';
@@ -21,6 +21,7 @@ export * as PageLoadMetrics from './PageLoadMetricsHandler.js';
21
21
  export * as Renderer from './RendererHandler.js';
22
22
  export * as Samples from './SamplesHandler.js';
23
23
  export * as Screenshots from './ScreenshotsHandler.js';
24
+ export * as SelectorStats from './SelectorStatsHandler.js';
24
25
  export * as UserInteractions from './UserInteractionsHandler.js';
25
26
  export * as UserTimings from './UserTimingsHandler.js';
26
27
  export * as Warnings from './WarningsHandler.js';
@@ -1 +1 @@
1
- {"version":3,"file":"ModelHandlers.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/ModelHandlers.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,eAAe,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,kBAAkB,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,OAAO,KAAK,GAAG,MAAM,iBAAiB,CAAC;AACvC,OAAO,KAAK,aAAa,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,aAAa,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,iBAAiB,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,gBAAgB,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,YAAY,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,OAAO,KAAK,IAAI,MAAM,kBAAkB,CAAC;AACzC,OAAO,KAAK,eAAe,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,eAAe,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAC/C,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,gBAAgB,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC","sourcesContent":["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport * as Animations from './AnimationHandler.js';\nexport * as AuctionWorklets from './AuctionWorkletsHandler.js';\nexport * as ExtensionTraceData from './ExtensionTraceDataHandler.js';\nexport * as Frames from './FramesHandler.js';\nexport * as GPU from './GPUHandler.js';\nexport * as ImagePainting from './ImagePaintingHandler.js';\nexport * as Initiators from './InitiatorsHandler.js';\nexport * as Invalidations from './InvalidationsHandler.js';\nexport * as LargestImagePaint from './LargestImagePaintHandler.js';\nexport * as LargestTextPaint from './LargestTextPaintHandler.js';\nexport * as LayerTree from './LayerTreeHandler.js';\nexport * as LayoutShifts from './LayoutShiftsHandler.js';\nexport * as Memory from './MemoryHandler.js';\nexport * as Meta from './MetaHandler.js';\nexport * as NetworkRequests from './NetworkRequestsHandler.js';\nexport * as PageFrames from './PageFramesHandler.js';\nexport * as PageLoadMetrics from './PageLoadMetricsHandler.js';\nexport * as Renderer from './RendererHandler.js';\nexport * as Samples from './SamplesHandler.js';\nexport * as Screenshots from './ScreenshotsHandler.js';\nexport * as UserInteractions from './UserInteractionsHandler.js';\nexport * as UserTimings from './UserTimingsHandler.js';\nexport * as Warnings from './WarningsHandler.js';\nexport * as Workers from './WorkersHandler.js';\n"]}
1
+ {"version":3,"file":"ModelHandlers.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/ModelHandlers.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,eAAe,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,kBAAkB,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,OAAO,KAAK,GAAG,MAAM,iBAAiB,CAAC;AACvC,OAAO,KAAK,aAAa,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,aAAa,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,iBAAiB,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,gBAAgB,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,YAAY,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,OAAO,KAAK,IAAI,MAAM,kBAAkB,CAAC;AACzC,OAAO,KAAK,eAAe,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,eAAe,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAC/C,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,aAAa,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,gBAAgB,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC","sourcesContent":["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport * as Animations from './AnimationHandler.js';\nexport * as AuctionWorklets from './AuctionWorkletsHandler.js';\nexport * as ExtensionTraceData from './ExtensionTraceDataHandler.js';\nexport * as Frames from './FramesHandler.js';\nexport * as GPU from './GPUHandler.js';\nexport * as ImagePainting from './ImagePaintingHandler.js';\nexport * as Initiators from './InitiatorsHandler.js';\nexport * as Invalidations from './InvalidationsHandler.js';\nexport * as LargestImagePaint from './LargestImagePaintHandler.js';\nexport * as LargestTextPaint from './LargestTextPaintHandler.js';\nexport * as LayerTree from './LayerTreeHandler.js';\nexport * as LayoutShifts from './LayoutShiftsHandler.js';\nexport * as Memory from './MemoryHandler.js';\nexport * as Meta from './MetaHandler.js';\nexport * as NetworkRequests from './NetworkRequestsHandler.js';\nexport * as PageFrames from './PageFramesHandler.js';\nexport * as PageLoadMetrics from './PageLoadMetricsHandler.js';\nexport * as Renderer from './RendererHandler.js';\nexport * as Samples from './SamplesHandler.js';\nexport * as Screenshots from './ScreenshotsHandler.js';\nexport * as SelectorStats from './SelectorStatsHandler.js';\nexport * as UserInteractions from './UserInteractionsHandler.js';\nexport * as UserTimings from './UserTimingsHandler.js';\nexport * as Warnings from './WarningsHandler.js';\nexport * as Workers from './WorkersHandler.js';\n"]}
@@ -317,6 +317,10 @@ export async function finalize() {
317
317
  stackTrace: finalSendRequest.args.data.stackTrace,
318
318
  timing,
319
319
  url,
320
+ failed: request.resourceFinish?.args.data.didFail ?? false,
321
+ finished: Boolean(request.resourceFinish),
322
+ connectionId: request.receiveResponse.args.data.connectionId,
323
+ connectionReused: request.receiveResponse.args.data.connectionReused,
320
324
  },
321
325
  },
322
326
  cat: 'loading',
@@ -1 +1 @@
1
- {"version":3,"file":"NetworkRequestsHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/NetworkRequestsHandler.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport {type TraceEventHandlerName, HandlerState} from './types.js';\n\nimport {data as metaHandlerData} from './MetaHandler.js';\nimport * as Helpers from '../helpers/helpers.js';\n\nimport * as Types from '../types/types.js';\n\nconst MILLISECONDS_TO_MICROSECONDS = 1000;\nconst SECONDS_TO_MICROSECONDS = 1000000;\n\n// Network requests from traces are actually formed of 5 trace records.\n// This handler tracks all trace records based on the request ID, and\n// then creates a new synthetic trace event for those network requests.\n//\n// This interface, then, defines the shape of the object we intend to\n// keep for each request in the trace. In the finalize we will convert\n// these 5 types of trace records to a synthetic complete event that\n// represents a composite of these trace records.\ninterface TraceEventsForNetworkRequest {\n changePriority?: Types.TraceEvents.TraceEventResourceChangePriority;\n willSendRequests?: Types.TraceEvents.TraceEventResourceWillSendRequest[];\n sendRequests?: Types.TraceEvents.TraceEventResourceSendRequest[];\n receiveResponse?: Types.TraceEvents.TraceEventResourceReceiveResponse;\n resourceFinish?: Types.TraceEvents.TraceEventResourceFinish;\n receivedData?: Types.TraceEvents.TraceEventResourceReceivedData[];\n resourceMarkAsCached?: Types.TraceEvents.TraceEventResourceMarkAsCached;\n}\n\ninterface NetworkRequestData {\n byOrigin: Map<string, {\n renderBlocking: Types.TraceEvents.SyntheticNetworkRequest[],\n nonRenderBlocking: Types.TraceEvents.SyntheticNetworkRequest[],\n all: Types.TraceEvents.SyntheticNetworkRequest[],\n }>;\n byTime: Types.TraceEvents.SyntheticNetworkRequest[];\n}\n\nconst requestMap = new Map<string, TraceEventsForNetworkRequest>();\nconst requestsByOrigin = new Map<string, {\n renderBlocking: Types.TraceEvents.SyntheticNetworkRequest[],\n nonRenderBlocking: Types.TraceEvents.SyntheticNetworkRequest[],\n all: Types.TraceEvents.SyntheticNetworkRequest[],\n}>();\nconst requestsByTime: Types.TraceEvents.SyntheticNetworkRequest[] = [];\n\nfunction storeTraceEventWithRequestId<K extends keyof TraceEventsForNetworkRequest>(\n requestId: string, key: K, value: TraceEventsForNetworkRequest[K]): void {\n if (!requestMap.has(requestId)) {\n requestMap.set(requestId, {});\n }\n\n const traceEvents = requestMap.get(requestId);\n if (!traceEvents) {\n throw new Error(`Unable to locate trace events for request ID ${requestId}`);\n }\n\n if (Array.isArray(traceEvents[key])) {\n const target = traceEvents[key] as Types.TraceEvents.TraceEventData[];\n const values = value as Types.TraceEvents.TraceEventData[];\n target.push(...values);\n } else {\n traceEvents[key] = value;\n }\n}\n\nfunction firstPositiveValueInList(entries: number[]): number {\n for (const entry of entries) {\n if (entry > 0) {\n return entry;\n }\n }\n\n // In the event we don't find a positive value, we return 0 so as to\n // be a mathematical noop. It's typically not correct to return – say –\n // a -1 here because it would affect the calculation of stats below.\n return 0;\n}\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\nexport function reset(): void {\n requestsByOrigin.clear();\n requestMap.clear();\n requestsByTime.length = 0;\n\n handlerState = HandlerState.UNINITIALIZED;\n}\n\nexport function initialize(): void {\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Network Request handler is not initialized');\n }\n\n if (Types.TraceEvents.isTraceEventResourceChangePriority(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'changePriority', event);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceWillSendRequest(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'willSendRequests', [event]);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceSendRequest(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'sendRequests', [event]);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceReceiveResponse(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'receiveResponse', event);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceReceivedData(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'receivedData', [event]);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceFinish(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'resourceFinish', event);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceMarkAsCached(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'resourceMarkAsCached', event);\n return;\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Network Request handler is not initialized');\n }\n\n const {rendererProcessesByFrame} = metaHandlerData();\n for (const [requestId, request] of requestMap.entries()) {\n // If we have an incomplete set of events here, we choose to drop the network\n // request rather than attempt to synthesize the missing data.\n if (!request.sendRequests || !request.receiveResponse) {\n continue;\n }\n\n // In the data we may get multiple willSendRequests and sendRequests, which\n // will indicate that there are redirects for a given (sub)resource. In the\n // case of a navigation, e.g., example.com/ we will get willSendRequests,\n // and we should use these to calculate time spent in redirects.\n // In the case of sub-resources, however, e.g., example.com/foo.js we will\n // *only* get sendRequests, and we use these instead of willSendRequests\n // to detect the time in redirects. We always use the sendRequest for the\n // url, priority etc since it contains those values, but we use the\n // willSendRequest (if it exists) to calculate the timestamp and durations\n // of redirects.\n const redirects: Types.TraceEvents.SyntheticNetworkRedirect[] = [];\n for (let i = 0; i < request.sendRequests.length - 1; i++) {\n const sendRequest = request.sendRequests[i];\n const nextSendRequest = request.sendRequests[i + 1];\n\n // Use the willSendRequests as the source for redirects if possible.\n // We default to those of the sendRequests, however, since willSendRequest\n // is not guaranteed to be present in the data for every request.\n let ts = sendRequest.ts;\n let dur = Types.Timing.MicroSeconds(nextSendRequest.ts - sendRequest.ts);\n if (request.willSendRequests && request.willSendRequests[i] && request.willSendRequests[i + 1]) {\n const willSendRequest = request.willSendRequests[i];\n const nextWillSendRequest = request.willSendRequests[i + 1];\n ts = willSendRequest.ts;\n dur = Types.Timing.MicroSeconds(nextWillSendRequest.ts - willSendRequest.ts);\n }\n\n redirects.push({\n url: sendRequest.args.data.url,\n priority: sendRequest.args.data.priority,\n requestMethod: sendRequest.args.data.requestMethod,\n ts,\n dur,\n });\n }\n\n // If a ResourceFinish event with an encoded data length is received,\n // then the resource was not cached; it was fetched before it was\n // requested, e.g. because it was pushed in this navigation.\n const isPushedResource = request.resourceFinish?.args.data.encodedDataLength !== 0;\n // This works around crbug.com/998397, which reports pushed resources, and resources served by a service worker as disk cached.\n const isDiskCached = request.receiveResponse.args.data.fromCache &&\n !request.receiveResponse.args.data.fromServiceWorker && !isPushedResource;\n // If the request contains a resourceMarkAsCached event, it was served from memory cache.\n const isMemoryCached = request.resourceMarkAsCached !== undefined;\n\n // The timing data returned is from the original (uncached) request, which\n // means that if we leave the above network record data as-is when the\n // request came from either the disk cache or memory cache, our calculations\n // will be incorrect.\n //\n // Here we add a flag so when we calculate the timestamps of the various\n // events, we can overwrite them.\n // These timestamps may not be perfect (indeed they don't always match\n // the Network CDP domain exactly, which is likely an artifact of the way\n // the data is routed on the backend), but they're the closest we have.\n const isCached = isMemoryCached || isDiskCached;\n\n const timing = request.receiveResponse.args.data.timing;\n // If a non-cached request has no |timing| indicates data URLs, we ignore it.\n if (!timing && !isCached) {\n continue;\n }\n\n const firstSendRequest = request.sendRequests[0];\n const finalSendRequest = request.sendRequests[request.sendRequests.length - 1];\n\n const initialPriority = finalSendRequest.args.data.priority;\n let finalPriority = initialPriority;\n if (request.changePriority) {\n finalPriority = request.changePriority.args.data.priority;\n }\n\n // Start time\n // =======================\n // The time where the request started, which is either the first willSendRequest\n // event if there is one, or, if there is not, the sendRequest.\n const startTime = (request.willSendRequests && request.willSendRequests.length) ?\n Types.Timing.MicroSeconds(request.willSendRequests[0].ts) :\n Types.Timing.MicroSeconds(firstSendRequest.ts);\n\n // End redirect time\n // =======================\n // It's possible that when we start requesting data we will receive redirections.\n // Here we note the time of the *last* willSendRequest / sendRequest event,\n // which is used later on in the calculations for time queueing etc.\n const endRedirectTime = (request.willSendRequests && request.willSendRequests.length) ?\n Types.Timing.MicroSeconds(request.willSendRequests[request.willSendRequests.length - 1].ts) :\n Types.Timing.MicroSeconds(finalSendRequest.ts);\n\n // Finish time and end time\n // =======================\n // The finish time and the end time are subtly different.\n // - Finish time: records the point at which the network stack stopped receiving the data\n // - End time: the timestamp of the finish event itself (if one exists)\n //\n // The end time, then, will be slightly after the finish time.\n const endTime = request.resourceFinish ? request.resourceFinish.ts : endRedirectTime;\n const finishTime = request.resourceFinish?.args.data.finishTime ?\n Types.Timing.MicroSeconds(request.resourceFinish.args.data.finishTime * SECONDS_TO_MICROSECONDS) :\n Types.Timing.MicroSeconds(endTime);\n\n // Network duration\n // =======================\n // Time spent on the network.\n const networkDuration = isCached ? Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((finishTime || endRedirectTime) - endRedirectTime);\n\n // Processing duration\n // =======================\n // Time spent from start to end.\n const processingDuration = Types.Timing.MicroSeconds(endTime - (finishTime || endTime));\n\n // Redirection duration\n // =======================\n // Time between the first willSendRequest / sendRequest and last. This we place in *front* of the\n // queueing, since the queueing time that we know about from the trace data is only the last request,\n // i.e., the one that occurs after all the redirects.\n const redirectionDuration = Types.Timing.MicroSeconds(endRedirectTime - startTime);\n\n // Queueing\n // =======================\n // The amount of time queueing is the time between the request's start time to the requestTime\n // arg recorded in the receiveResponse event. In the cases where the recorded start time is larger\n // that the requestTime we set queueing time to zero.\n const queueing = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds(Platform.NumberUtilities.clamp(\n (timing.requestTime * SECONDS_TO_MICROSECONDS - endRedirectTime), 0, Number.MAX_VALUE));\n\n // Stalled\n // =======================\n // If the request is cached, the amount of time stalled is the time between the start time and\n // receiving a response.\n // Otherwise it is whichever positive number comes first from the following timing info:\n // DNS start, Connection start, Send Start, or the time duration between our start time and\n // receiving a response.\n const stalled = isCached ? Types.Timing.MicroSeconds(request.receiveResponse.ts - startTime) :\n Types.Timing.MicroSeconds(firstPositiveValueInList([\n timing.dnsStart * MILLISECONDS_TO_MICROSECONDS,\n timing.connectStart * MILLISECONDS_TO_MICROSECONDS,\n timing.sendStart * MILLISECONDS_TO_MICROSECONDS,\n (request.receiveResponse.ts - endRedirectTime),\n ]));\n\n // Sending HTTP request\n // =======================\n // Time when the HTTP request is sent.\n const sendStartTime = isCached ?\n startTime :\n Types.Timing.MicroSeconds(\n timing.requestTime * SECONDS_TO_MICROSECONDS + timing.sendStart * MILLISECONDS_TO_MICROSECONDS);\n\n // Waiting\n // =======================\n // Time from when the send finished going to when the headers were received.\n const waiting = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.receiveHeadersEnd - timing.sendEnd) * MILLISECONDS_TO_MICROSECONDS);\n\n // Download\n // =======================\n // Time from receipt of headers to the finish time.\n const downloadStart = isCached ?\n startTime :\n Types.Timing.MicroSeconds(\n timing.requestTime * SECONDS_TO_MICROSECONDS + timing.receiveHeadersEnd * MILLISECONDS_TO_MICROSECONDS);\n const download = isCached ? Types.Timing.MicroSeconds(endTime - request.receiveResponse.ts) :\n Types.Timing.MicroSeconds(((finishTime || downloadStart) - downloadStart));\n\n const totalTime = Types.Timing.MicroSeconds(networkDuration + processingDuration);\n\n // Collect a few values from the timing info.\n // If the Network request is cached, we zero out them.\n const dnsLookup = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.dnsEnd - timing.dnsStart) * MILLISECONDS_TO_MICROSECONDS);\n const ssl = isCached ? Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.sslEnd - timing.sslStart) * MILLISECONDS_TO_MICROSECONDS);\n const proxyNegotiation = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.proxyEnd - timing.proxyStart) * MILLISECONDS_TO_MICROSECONDS);\n const requestSent = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.sendEnd - timing.sendStart) * MILLISECONDS_TO_MICROSECONDS);\n const initialConnection = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.connectEnd - timing.connectStart) * MILLISECONDS_TO_MICROSECONDS);\n\n // Finally get some of the general data from the trace events.\n const {frame, url, renderBlocking} = finalSendRequest.args.data;\n const {encodedDataLength, decodedBodyLength} =\n request.resourceFinish ? request.resourceFinish.args.data : {encodedDataLength: 0, decodedBodyLength: 0};\n const {host, protocol, pathname, search} = new URL(url);\n const isHttps = protocol === 'https:';\n const requestingFrameUrl =\n Helpers.Trace.activeURLForFrameAtTime(frame, finalSendRequest.ts, rendererProcessesByFrame) || '';\n\n // Construct a synthetic trace event for this network request.\n const networkEvent: Types.TraceEvents.SyntheticNetworkRequest = {\n args: {\n data: {\n // All data we create from trace events should be added to |syntheticData|.\n syntheticData: {\n dnsLookup,\n download,\n downloadStart,\n finishTime,\n initialConnection,\n isDiskCached,\n isHttps,\n isMemoryCached,\n isPushedResource,\n networkDuration,\n processingDuration,\n proxyNegotiation,\n queueing,\n redirectionDuration,\n requestSent,\n sendStartTime,\n ssl,\n stalled,\n totalTime,\n waiting,\n },\n // All fields below are from TraceEventsForNetworkRequest.\n decodedBodyLength,\n encodedDataLength,\n frame,\n fromServiceWorker: request.receiveResponse.args.data.fromServiceWorker,\n isLinkPreload: request.receiveResponse.args.data.isLinkPreload || false,\n host,\n mimeType: request.receiveResponse.args.data.mimeType,\n pathname,\n priority: finalPriority,\n initialPriority,\n protocol,\n redirects,\n // In the event the property isn't set, assume non-blocking.\n renderBlocking: renderBlocking ? renderBlocking : 'non_blocking',\n requestId,\n requestingFrameUrl,\n requestMethod: finalSendRequest.args.data.requestMethod,\n resourceType: finalSendRequest.args.data.resourceType,\n search,\n statusCode: request.receiveResponse.args.data.statusCode,\n responseHeaders: request.receiveResponse.args.data.headers || [],\n fetchPriorityHint: finalSendRequest.args.data.fetchPriorityHint,\n initiator: finalSendRequest.args.data.initiator,\n stackTrace: finalSendRequest.args.data.stackTrace,\n timing,\n url,\n },\n },\n cat: 'loading',\n name: 'SyntheticNetworkRequest',\n ph: Types.TraceEvents.Phase.COMPLETE,\n dur: Types.Timing.MicroSeconds(endTime - startTime),\n tdur: Types.Timing.MicroSeconds(endTime - startTime),\n ts: Types.Timing.MicroSeconds(startTime),\n tts: Types.Timing.MicroSeconds(startTime),\n pid: finalSendRequest.pid,\n tid: finalSendRequest.tid,\n };\n\n const requests = Platform.MapUtilities.getWithDefault(requestsByOrigin, host, () => {\n return {\n renderBlocking: [],\n nonRenderBlocking: [],\n all: [],\n };\n });\n\n // For ease of rendering we sometimes want to differentiate between\n // render-blocking and non-render-blocking, so we divide the data here.\n if (networkEvent.args.data.renderBlocking === 'non_blocking') {\n requests.nonRenderBlocking.push(networkEvent);\n } else {\n requests.renderBlocking.push(networkEvent);\n }\n\n // However, there are also times where we just want to loop through all\n // the captured requests, so here we store all of them together.\n requests.all.push(networkEvent);\n requestsByTime.push(networkEvent);\n }\n\n handlerState = HandlerState.FINALIZED;\n}\n\nexport function data(): NetworkRequestData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('Network Request handler is not finalized');\n }\n\n return {\n byOrigin: requestsByOrigin,\n byTime: requestsByTime,\n };\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Meta'];\n}\n"]}
1
+ {"version":3,"file":"NetworkRequestsHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/NetworkRequestsHandler.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport {type TraceEventHandlerName, HandlerState} from './types.js';\n\nimport {data as metaHandlerData} from './MetaHandler.js';\nimport * as Helpers from '../helpers/helpers.js';\n\nimport * as Types from '../types/types.js';\n\nconst MILLISECONDS_TO_MICROSECONDS = 1000;\nconst SECONDS_TO_MICROSECONDS = 1000000;\n\n// Network requests from traces are actually formed of 5 trace records.\n// This handler tracks all trace records based on the request ID, and\n// then creates a new synthetic trace event for those network requests.\n//\n// This interface, then, defines the shape of the object we intend to\n// keep for each request in the trace. In the finalize we will convert\n// these 5 types of trace records to a synthetic complete event that\n// represents a composite of these trace records.\ninterface TraceEventsForNetworkRequest {\n changePriority?: Types.TraceEvents.TraceEventResourceChangePriority;\n willSendRequests?: Types.TraceEvents.TraceEventResourceWillSendRequest[];\n sendRequests?: Types.TraceEvents.TraceEventResourceSendRequest[];\n receiveResponse?: Types.TraceEvents.TraceEventResourceReceiveResponse;\n resourceFinish?: Types.TraceEvents.TraceEventResourceFinish;\n receivedData?: Types.TraceEvents.TraceEventResourceReceivedData[];\n resourceMarkAsCached?: Types.TraceEvents.TraceEventResourceMarkAsCached;\n}\n\ninterface NetworkRequestData {\n byOrigin: Map<string, {\n renderBlocking: Types.TraceEvents.SyntheticNetworkRequest[],\n nonRenderBlocking: Types.TraceEvents.SyntheticNetworkRequest[],\n all: Types.TraceEvents.SyntheticNetworkRequest[],\n }>;\n byTime: Types.TraceEvents.SyntheticNetworkRequest[];\n}\n\nconst requestMap = new Map<string, TraceEventsForNetworkRequest>();\nconst requestsByOrigin = new Map<string, {\n renderBlocking: Types.TraceEvents.SyntheticNetworkRequest[],\n nonRenderBlocking: Types.TraceEvents.SyntheticNetworkRequest[],\n all: Types.TraceEvents.SyntheticNetworkRequest[],\n}>();\nconst requestsByTime: Types.TraceEvents.SyntheticNetworkRequest[] = [];\n\nfunction storeTraceEventWithRequestId<K extends keyof TraceEventsForNetworkRequest>(\n requestId: string, key: K, value: TraceEventsForNetworkRequest[K]): void {\n if (!requestMap.has(requestId)) {\n requestMap.set(requestId, {});\n }\n\n const traceEvents = requestMap.get(requestId);\n if (!traceEvents) {\n throw new Error(`Unable to locate trace events for request ID ${requestId}`);\n }\n\n if (Array.isArray(traceEvents[key])) {\n const target = traceEvents[key] as Types.TraceEvents.TraceEventData[];\n const values = value as Types.TraceEvents.TraceEventData[];\n target.push(...values);\n } else {\n traceEvents[key] = value;\n }\n}\n\nfunction firstPositiveValueInList(entries: number[]): number {\n for (const entry of entries) {\n if (entry > 0) {\n return entry;\n }\n }\n\n // In the event we don't find a positive value, we return 0 so as to\n // be a mathematical noop. It's typically not correct to return – say –\n // a -1 here because it would affect the calculation of stats below.\n return 0;\n}\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\nexport function reset(): void {\n requestsByOrigin.clear();\n requestMap.clear();\n requestsByTime.length = 0;\n\n handlerState = HandlerState.UNINITIALIZED;\n}\n\nexport function initialize(): void {\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Network Request handler is not initialized');\n }\n\n if (Types.TraceEvents.isTraceEventResourceChangePriority(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'changePriority', event);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceWillSendRequest(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'willSendRequests', [event]);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceSendRequest(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'sendRequests', [event]);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceReceiveResponse(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'receiveResponse', event);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceReceivedData(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'receivedData', [event]);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceFinish(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'resourceFinish', event);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceMarkAsCached(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'resourceMarkAsCached', event);\n return;\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Network Request handler is not initialized');\n }\n\n const {rendererProcessesByFrame} = metaHandlerData();\n for (const [requestId, request] of requestMap.entries()) {\n // If we have an incomplete set of events here, we choose to drop the network\n // request rather than attempt to synthesize the missing data.\n if (!request.sendRequests || !request.receiveResponse) {\n continue;\n }\n\n // In the data we may get multiple willSendRequests and sendRequests, which\n // will indicate that there are redirects for a given (sub)resource. In the\n // case of a navigation, e.g., example.com/ we will get willSendRequests,\n // and we should use these to calculate time spent in redirects.\n // In the case of sub-resources, however, e.g., example.com/foo.js we will\n // *only* get sendRequests, and we use these instead of willSendRequests\n // to detect the time in redirects. We always use the sendRequest for the\n // url, priority etc since it contains those values, but we use the\n // willSendRequest (if it exists) to calculate the timestamp and durations\n // of redirects.\n const redirects: Types.TraceEvents.SyntheticNetworkRedirect[] = [];\n for (let i = 0; i < request.sendRequests.length - 1; i++) {\n const sendRequest = request.sendRequests[i];\n const nextSendRequest = request.sendRequests[i + 1];\n\n // Use the willSendRequests as the source for redirects if possible.\n // We default to those of the sendRequests, however, since willSendRequest\n // is not guaranteed to be present in the data for every request.\n let ts = sendRequest.ts;\n let dur = Types.Timing.MicroSeconds(nextSendRequest.ts - sendRequest.ts);\n if (request.willSendRequests && request.willSendRequests[i] && request.willSendRequests[i + 1]) {\n const willSendRequest = request.willSendRequests[i];\n const nextWillSendRequest = request.willSendRequests[i + 1];\n ts = willSendRequest.ts;\n dur = Types.Timing.MicroSeconds(nextWillSendRequest.ts - willSendRequest.ts);\n }\n\n redirects.push({\n url: sendRequest.args.data.url,\n priority: sendRequest.args.data.priority,\n requestMethod: sendRequest.args.data.requestMethod,\n ts,\n dur,\n });\n }\n\n // If a ResourceFinish event with an encoded data length is received,\n // then the resource was not cached; it was fetched before it was\n // requested, e.g. because it was pushed in this navigation.\n const isPushedResource = request.resourceFinish?.args.data.encodedDataLength !== 0;\n // This works around crbug.com/998397, which reports pushed resources, and resources served by a service worker as disk cached.\n const isDiskCached = request.receiveResponse.args.data.fromCache &&\n !request.receiveResponse.args.data.fromServiceWorker && !isPushedResource;\n // If the request contains a resourceMarkAsCached event, it was served from memory cache.\n const isMemoryCached = request.resourceMarkAsCached !== undefined;\n\n // The timing data returned is from the original (uncached) request, which\n // means that if we leave the above network record data as-is when the\n // request came from either the disk cache or memory cache, our calculations\n // will be incorrect.\n //\n // Here we add a flag so when we calculate the timestamps of the various\n // events, we can overwrite them.\n // These timestamps may not be perfect (indeed they don't always match\n // the Network CDP domain exactly, which is likely an artifact of the way\n // the data is routed on the backend), but they're the closest we have.\n const isCached = isMemoryCached || isDiskCached;\n\n const timing = request.receiveResponse.args.data.timing;\n // If a non-cached request has no |timing| indicates data URLs, we ignore it.\n if (!timing && !isCached) {\n continue;\n }\n\n const firstSendRequest = request.sendRequests[0];\n const finalSendRequest = request.sendRequests[request.sendRequests.length - 1];\n\n const initialPriority = finalSendRequest.args.data.priority;\n let finalPriority = initialPriority;\n if (request.changePriority) {\n finalPriority = request.changePriority.args.data.priority;\n }\n\n // Start time\n // =======================\n // The time where the request started, which is either the first willSendRequest\n // event if there is one, or, if there is not, the sendRequest.\n const startTime = (request.willSendRequests && request.willSendRequests.length) ?\n Types.Timing.MicroSeconds(request.willSendRequests[0].ts) :\n Types.Timing.MicroSeconds(firstSendRequest.ts);\n\n // End redirect time\n // =======================\n // It's possible that when we start requesting data we will receive redirections.\n // Here we note the time of the *last* willSendRequest / sendRequest event,\n // which is used later on in the calculations for time queueing etc.\n const endRedirectTime = (request.willSendRequests && request.willSendRequests.length) ?\n Types.Timing.MicroSeconds(request.willSendRequests[request.willSendRequests.length - 1].ts) :\n Types.Timing.MicroSeconds(finalSendRequest.ts);\n\n // Finish time and end time\n // =======================\n // The finish time and the end time are subtly different.\n // - Finish time: records the point at which the network stack stopped receiving the data\n // - End time: the timestamp of the finish event itself (if one exists)\n //\n // The end time, then, will be slightly after the finish time.\n const endTime = request.resourceFinish ? request.resourceFinish.ts : endRedirectTime;\n const finishTime = request.resourceFinish?.args.data.finishTime ?\n Types.Timing.MicroSeconds(request.resourceFinish.args.data.finishTime * SECONDS_TO_MICROSECONDS) :\n Types.Timing.MicroSeconds(endTime);\n\n // Network duration\n // =======================\n // Time spent on the network.\n const networkDuration = isCached ? Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((finishTime || endRedirectTime) - endRedirectTime);\n\n // Processing duration\n // =======================\n // Time spent from start to end.\n const processingDuration = Types.Timing.MicroSeconds(endTime - (finishTime || endTime));\n\n // Redirection duration\n // =======================\n // Time between the first willSendRequest / sendRequest and last. This we place in *front* of the\n // queueing, since the queueing time that we know about from the trace data is only the last request,\n // i.e., the one that occurs after all the redirects.\n const redirectionDuration = Types.Timing.MicroSeconds(endRedirectTime - startTime);\n\n // Queueing\n // =======================\n // The amount of time queueing is the time between the request's start time to the requestTime\n // arg recorded in the receiveResponse event. In the cases where the recorded start time is larger\n // that the requestTime we set queueing time to zero.\n const queueing = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds(Platform.NumberUtilities.clamp(\n (timing.requestTime * SECONDS_TO_MICROSECONDS - endRedirectTime), 0, Number.MAX_VALUE));\n\n // Stalled\n // =======================\n // If the request is cached, the amount of time stalled is the time between the start time and\n // receiving a response.\n // Otherwise it is whichever positive number comes first from the following timing info:\n // DNS start, Connection start, Send Start, or the time duration between our start time and\n // receiving a response.\n const stalled = isCached ? Types.Timing.MicroSeconds(request.receiveResponse.ts - startTime) :\n Types.Timing.MicroSeconds(firstPositiveValueInList([\n timing.dnsStart * MILLISECONDS_TO_MICROSECONDS,\n timing.connectStart * MILLISECONDS_TO_MICROSECONDS,\n timing.sendStart * MILLISECONDS_TO_MICROSECONDS,\n (request.receiveResponse.ts - endRedirectTime),\n ]));\n\n // Sending HTTP request\n // =======================\n // Time when the HTTP request is sent.\n const sendStartTime = isCached ?\n startTime :\n Types.Timing.MicroSeconds(\n timing.requestTime * SECONDS_TO_MICROSECONDS + timing.sendStart * MILLISECONDS_TO_MICROSECONDS);\n\n // Waiting\n // =======================\n // Time from when the send finished going to when the headers were received.\n const waiting = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.receiveHeadersEnd - timing.sendEnd) * MILLISECONDS_TO_MICROSECONDS);\n\n // Download\n // =======================\n // Time from receipt of headers to the finish time.\n const downloadStart = isCached ?\n startTime :\n Types.Timing.MicroSeconds(\n timing.requestTime * SECONDS_TO_MICROSECONDS + timing.receiveHeadersEnd * MILLISECONDS_TO_MICROSECONDS);\n const download = isCached ? Types.Timing.MicroSeconds(endTime - request.receiveResponse.ts) :\n Types.Timing.MicroSeconds(((finishTime || downloadStart) - downloadStart));\n\n const totalTime = Types.Timing.MicroSeconds(networkDuration + processingDuration);\n\n // Collect a few values from the timing info.\n // If the Network request is cached, we zero out them.\n const dnsLookup = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.dnsEnd - timing.dnsStart) * MILLISECONDS_TO_MICROSECONDS);\n const ssl = isCached ? Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.sslEnd - timing.sslStart) * MILLISECONDS_TO_MICROSECONDS);\n const proxyNegotiation = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.proxyEnd - timing.proxyStart) * MILLISECONDS_TO_MICROSECONDS);\n const requestSent = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.sendEnd - timing.sendStart) * MILLISECONDS_TO_MICROSECONDS);\n const initialConnection = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.connectEnd - timing.connectStart) * MILLISECONDS_TO_MICROSECONDS);\n\n // Finally get some of the general data from the trace events.\n const {frame, url, renderBlocking} = finalSendRequest.args.data;\n const {encodedDataLength, decodedBodyLength} =\n request.resourceFinish ? request.resourceFinish.args.data : {encodedDataLength: 0, decodedBodyLength: 0};\n const {host, protocol, pathname, search} = new URL(url);\n const isHttps = protocol === 'https:';\n const requestingFrameUrl =\n Helpers.Trace.activeURLForFrameAtTime(frame, finalSendRequest.ts, rendererProcessesByFrame) || '';\n\n // Construct a synthetic trace event for this network request.\n const networkEvent: Types.TraceEvents.SyntheticNetworkRequest = {\n args: {\n data: {\n // All data we create from trace events should be added to |syntheticData|.\n syntheticData: {\n dnsLookup,\n download,\n downloadStart,\n finishTime,\n initialConnection,\n isDiskCached,\n isHttps,\n isMemoryCached,\n isPushedResource,\n networkDuration,\n processingDuration,\n proxyNegotiation,\n queueing,\n redirectionDuration,\n requestSent,\n sendStartTime,\n ssl,\n stalled,\n totalTime,\n waiting,\n },\n // All fields below are from TraceEventsForNetworkRequest.\n decodedBodyLength,\n encodedDataLength,\n frame,\n fromServiceWorker: request.receiveResponse.args.data.fromServiceWorker,\n isLinkPreload: request.receiveResponse.args.data.isLinkPreload || false,\n host,\n mimeType: request.receiveResponse.args.data.mimeType,\n pathname,\n priority: finalPriority,\n initialPriority,\n protocol,\n redirects,\n // In the event the property isn't set, assume non-blocking.\n renderBlocking: renderBlocking ? renderBlocking : 'non_blocking',\n requestId,\n requestingFrameUrl,\n requestMethod: finalSendRequest.args.data.requestMethod,\n resourceType: finalSendRequest.args.data.resourceType,\n search,\n statusCode: request.receiveResponse.args.data.statusCode,\n responseHeaders: request.receiveResponse.args.data.headers || [],\n fetchPriorityHint: finalSendRequest.args.data.fetchPriorityHint,\n initiator: finalSendRequest.args.data.initiator,\n stackTrace: finalSendRequest.args.data.stackTrace,\n timing,\n url,\n failed: request.resourceFinish?.args.data.didFail ?? false,\n finished: Boolean(request.resourceFinish),\n connectionId: request.receiveResponse.args.data.connectionId,\n connectionReused: request.receiveResponse.args.data.connectionReused,\n },\n },\n cat: 'loading',\n name: 'SyntheticNetworkRequest',\n ph: Types.TraceEvents.Phase.COMPLETE,\n dur: Types.Timing.MicroSeconds(endTime - startTime),\n tdur: Types.Timing.MicroSeconds(endTime - startTime),\n ts: Types.Timing.MicroSeconds(startTime),\n tts: Types.Timing.MicroSeconds(startTime),\n pid: finalSendRequest.pid,\n tid: finalSendRequest.tid,\n };\n\n const requests = Platform.MapUtilities.getWithDefault(requestsByOrigin, host, () => {\n return {\n renderBlocking: [],\n nonRenderBlocking: [],\n all: [],\n };\n });\n\n // For ease of rendering we sometimes want to differentiate between\n // render-blocking and non-render-blocking, so we divide the data here.\n if (networkEvent.args.data.renderBlocking === 'non_blocking') {\n requests.nonRenderBlocking.push(networkEvent);\n } else {\n requests.renderBlocking.push(networkEvent);\n }\n\n // However, there are also times where we just want to loop through all\n // the captured requests, so here we store all of them together.\n requests.all.push(networkEvent);\n requestsByTime.push(networkEvent);\n }\n\n handlerState = HandlerState.FINALIZED;\n}\n\nexport function data(): NetworkRequestData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('Network Request handler is not finalized');\n }\n\n return {\n byOrigin: requestsByOrigin,\n byTime: requestsByTime,\n };\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Meta'];\n}\n"]}
@@ -0,0 +1,9 @@
1
+ import * as Types from '../types/types.js';
2
+ export declare function reset(): void;
3
+ export declare function handleEvent(event: Types.TraceEvents.TraceEventData): void;
4
+ export interface SelectorStatsData {
5
+ dataForUpdateLayoutEvent: Map<Types.TraceEvents.TraceEventUpdateLayoutTree, {
6
+ timings: Types.TraceEvents.SelectorTiming[];
7
+ }>;
8
+ }
9
+ export declare function data(): SelectorStatsData;
@@ -0,0 +1,28 @@
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
+ let lastUpdateLayoutTreeEvent = null;
6
+ const selectorDataForUpdateLayoutTree = new Map();
7
+ export function reset() {
8
+ lastUpdateLayoutTreeEvent = null;
9
+ selectorDataForUpdateLayoutTree.clear();
10
+ }
11
+ export function handleEvent(event) {
12
+ if (Types.TraceEvents.isTraceEventSelectorStats(event) && lastUpdateLayoutTreeEvent && event.args.selector_stats) {
13
+ selectorDataForUpdateLayoutTree.set(lastUpdateLayoutTreeEvent, {
14
+ timings: event.args.selector_stats.selector_timings,
15
+ });
16
+ return;
17
+ }
18
+ if (Types.TraceEvents.isTraceEventUpdateLayoutTree(event)) {
19
+ lastUpdateLayoutTreeEvent = event;
20
+ return;
21
+ }
22
+ }
23
+ export function data() {
24
+ return {
25
+ dataForUpdateLayoutEvent: selectorDataForUpdateLayoutTree,
26
+ };
27
+ }
28
+ //# sourceMappingURL=SelectorStatsHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectorStatsHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/SelectorStatsHandler.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAE3C,IAAI,yBAAyB,GAAsD,IAAI,CAAC;AAExF,MAAM,+BAA+B,GAAG,IAAI,GAAG,EAE3C,CAAC;AAEL,MAAM,UAAU,KAAK;IACnB,yBAAyB,GAAG,IAAI,CAAC;IACjC,+BAA+B,CAAC,KAAK,EAAE,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAuC;IACjE,IAAI,KAAK,CAAC,WAAW,CAAC,yBAAyB,CAAC,KAAK,CAAC,IAAI,yBAAyB,IAAI,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;QACjH,+BAA+B,CAAC,GAAG,CAAC,yBAAyB,EAAE;YAC7D,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,gBAAgB;SACpD,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,IAAI,KAAK,CAAC,WAAW,CAAC,4BAA4B,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1D,yBAAyB,GAAG,KAAK,CAAC;QAClC,OAAO;IACT,CAAC;AACH,CAAC;AAQD,MAAM,UAAU,IAAI;IAClB,OAAO;QACL,wBAAwB,EAAE,+BAA+B;KAC1D,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 Types from '../types/types.js';\n\nlet lastUpdateLayoutTreeEvent: Types.TraceEvents.TraceEventUpdateLayoutTree|null = null;\n\nconst selectorDataForUpdateLayoutTree = new Map<Types.TraceEvents.TraceEventUpdateLayoutTree, {\n timings: Types.TraceEvents.SelectorTiming[],\n}>();\n\nexport function reset(): void {\n lastUpdateLayoutTreeEvent = null;\n selectorDataForUpdateLayoutTree.clear();\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (Types.TraceEvents.isTraceEventSelectorStats(event) && lastUpdateLayoutTreeEvent && event.args.selector_stats) {\n selectorDataForUpdateLayoutTree.set(lastUpdateLayoutTreeEvent, {\n timings: event.args.selector_stats.selector_timings,\n });\n return;\n }\n\n if (Types.TraceEvents.isTraceEventUpdateLayoutTree(event)) {\n lastUpdateLayoutTreeEvent = event;\n return;\n }\n}\n\nexport interface SelectorStatsData {\n dataForUpdateLayoutEvent: Map<Types.TraceEvents.TraceEventUpdateLayoutTree, {\n timings: Types.TraceEvents.SelectorTiming[],\n }>;\n}\n\nexport function data(): SelectorStatsData {\n return {\n dataForUpdateLayoutEvent: selectorDataForUpdateLayoutTree,\n };\n}\n"]}
@@ -4,6 +4,8 @@ export declare const LONG_INTERACTION_THRESHOLD: Types.Timing.MicroSeconds;
4
4
  export interface UserInteractionsData {
5
5
  /** All the user events we found in the trace */
6
6
  allEvents: readonly Types.TraceEvents.TraceEventEventTiming[];
7
+ /** All the BeginCommitCompositorFrame events we found in the trace */
8
+ beginCommitCompositorFrameEvents: readonly Types.TraceEvents.TraceEventBeginCommitCompositorFrame[];
7
9
  /** All the interaction events we found in the trace that had an
8
10
  * interactionId and a duration > 0
9
11
  **/