@paulirish/trace_engine 0.0.10 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/analyze-trace.mjs +1 -1
- package/core/platform/DevToolsPath.d.ts +4 -13
- package/core/platform/DevToolsPath.js +7 -4
- package/core/platform/DevToolsPath.js.map +1 -7
- package/core/platform/MimeType.d.ts +27 -0
- package/core/platform/MimeType.js +119 -86
- package/core/platform/MimeType.js.map +1 -7
- package/core/platform/Timing.d.ts +7 -0
- package/core/platform/Timing.js +7 -4
- package/core/platform/Timing.js.map +1 -7
- package/core/platform/UIString.d.ts +2 -5
- package/core/platform/UIString.js +5 -2
- package/core/platform/UIString.js.map +1 -7
- package/core/platform/UserVisibleError.js +19 -10
- package/core/platform/UserVisibleError.js.map +1 -7
- package/core/platform/array-utilities.d.ts +48 -10
- package/core/platform/array-utilities.js +160 -124
- package/core/platform/array-utilities.js.map +1 -7
- package/core/platform/brand.d.ts +14 -0
- package/core/platform/brand.js +5 -1
- package/core/platform/brand.js.map +1 -7
- package/core/platform/date-utilities.js +10 -6
- package/core/platform/date-utilities.js.map +1 -7
- package/core/platform/dom-utilities.d.ts +3 -1
- package/core/platform/dom-utilities.js +94 -83
- package/core/platform/dom-utilities.js.map +1 -7
- package/core/platform/keyboard-utilities.d.ts +2 -0
- package/core/platform/keyboard-utilities.js +15 -24
- package/core/platform/keyboard-utilities.js.map +1 -7
- package/core/platform/map-utilities.d.ts +4 -0
- package/core/platform/map-utilities.js +66 -60
- package/core/platform/map-utilities.js.map +1 -7
- package/core/platform/number-utilities.js +66 -55
- package/core/platform/number-utilities.js.map +1 -7
- package/core/platform/platform.d.ts +5 -1
- package/core/platform/platform.js +54 -37
- package/core/platform/platform.js.map +1 -7
- package/core/platform/promise-utilities.d.ts +10 -0
- package/core/platform/promise-utilities.js +16 -8
- package/core/platform/promise-utilities.js.map +1 -7
- package/core/platform/set-utilities.js +20 -17
- package/core/platform/set-utilities.js.map +1 -7
- package/core/platform/string-utilities.d.ts +32 -1
- package/core/platform/string-utilities.js +453 -379
- package/core/platform/string-utilities.js.map +1 -7
- package/core/platform/typescript-utilities.d.ts +5 -5
- package/core/platform/typescript-utilities.js +19 -7
- package/core/platform/typescript-utilities.js.map +1 -7
- package/generated/protocol.d.ts +2081 -347
- package/generated/protocol.js +5 -2230
- package/models/cpu_profile/CPUProfileDataModel.d.ts +77 -0
- package/models/cpu_profile/CPUProfileDataModel.js +492 -359
- package/models/cpu_profile/CPUProfileDataModel.js.map +1 -7
- package/models/cpu_profile/ProfileTreeModel.d.ts +29 -0
- package/models/cpu_profile/ProfileTreeModel.js +87 -82
- package/models/cpu_profile/ProfileTreeModel.js.map +1 -7
- package/models/cpu_profile/cpu_profile.d.ts +3 -0
- package/models/cpu_profile/cpu_profile.js +7 -7
- package/models/cpu_profile/cpu_profile.js.map +1 -7
- package/models/trace/EntriesFilter.d.ts +55 -0
- package/models/trace/EntriesFilter.js +227 -166
- package/models/trace/EntriesFilter.js.map +1 -7
- package/models/trace/LegacyTracingModel.js.map +1 -7
- package/models/trace/ModelImpl.d.ts +110 -0
- package/models/trace/ModelImpl.js +161 -102
- package/models/trace/ModelImpl.js.map +1 -7
- package/models/trace/Processor.d.ts +36 -0
- package/models/trace/Processor.js +197 -163
- package/models/trace/Processor.js.map +1 -7
- package/models/trace/TracingManager.js.map +1 -7
- package/models/trace/extras/FetchNodes.d.ts +46 -0
- package/models/trace/extras/FetchNodes.js +132 -91
- package/models/trace/extras/FetchNodes.js.map +1 -7
- package/models/trace/extras/FilmStrip.d.ts +19 -0
- package/models/trace/extras/FilmStrip.js +38 -31
- package/models/trace/extras/FilmStrip.js.map +1 -7
- package/models/trace/extras/MainThreadActivity.d.ts +2 -0
- package/models/trace/extras/MainThreadActivity.js +72 -56
- package/models/trace/extras/MainThreadActivity.js.map +1 -7
- package/models/trace/extras/Metadata.d.ts +2 -0
- package/models/trace/extras/Metadata.js +42 -26
- package/models/trace/extras/Metadata.js.map +1 -7
- package/models/trace/extras/extras.js.map +1 -7
- package/models/trace/handlers/AnimationHandler.d.ts +8 -0
- package/models/trace/handlers/AnimationHandler.js +22 -20
- package/models/trace/handlers/AnimationHandler.js.map +1 -7
- package/models/trace/handlers/AuctionWorkletsHandler.d.ts +8 -0
- package/models/trace/handlers/AuctionWorkletsHandler.js +143 -89
- package/models/trace/handlers/AuctionWorkletsHandler.js.map +1 -7
- package/models/trace/handlers/FramesHandler.d.ts +76 -0
- package/models/trace/handlers/FramesHandler.js +424 -355
- package/models/trace/handlers/FramesHandler.js.map +1 -7
- package/models/trace/handlers/GPUHandler.d.ts +11 -0
- package/models/trace/handlers/GPUHandler.js +41 -37
- package/models/trace/handlers/GPUHandler.js.map +1 -7
- package/models/trace/handlers/InitiatorsHandler.d.ts +10 -0
- package/models/trace/handlers/InitiatorsHandler.js +164 -113
- package/models/trace/handlers/InitiatorsHandler.js.map +1 -7
- package/models/trace/handlers/InvalidationsHandler.d.ts +10 -0
- package/models/trace/handlers/InvalidationsHandler.js +101 -79
- package/models/trace/handlers/InvalidationsHandler.js.map +1 -7
- package/models/trace/handlers/LargestImagePaintHandler.d.ts +5 -0
- package/models/trace/handlers/LargestImagePaintHandler.js +32 -12
- package/models/trace/handlers/LargestImagePaintHandler.js.map +1 -7
- package/models/trace/handlers/LargestTextPaintHandler.d.ts +5 -0
- package/models/trace/handlers/LargestTextPaintHandler.js +20 -12
- package/models/trace/handlers/LargestTextPaintHandler.js.map +1 -7
- package/models/trace/handlers/LayerTreeHandler.d.ts +13 -0
- package/models/trace/handlers/LayerTreeHandler.js +96 -70
- package/models/trace/handlers/LayerTreeHandler.js.map +1 -7
- package/models/trace/handlers/LayoutShiftsHandler.d.ts +44 -0
- package/models/trace/handlers/LayoutShiftsHandler.js +304 -227
- package/models/trace/handlers/LayoutShiftsHandler.js.map +1 -7
- package/models/trace/handlers/MemoryHandler.d.ts +7 -0
- package/models/trace/handlers/MemoryHandler.js +14 -11
- package/models/trace/handlers/MemoryHandler.js.map +1 -7
- package/models/trace/handlers/MetaHandler.d.ts +37 -0
- package/models/trace/handlers/MetaHandler.js +314 -226
- package/models/trace/handlers/MetaHandler.js.map +1 -7
- package/models/trace/handlers/ModelHandlers.d.ts +21 -0
- package/models/trace/handlers/ModelHandlers.js +25 -22
- package/models/trace/handlers/ModelHandlers.js.map +1 -7
- package/models/trace/handlers/NetworkRequestsHandler.d.ts +17 -0
- package/models/trace/handlers/NetworkRequestsHandler.js +342 -218
- package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -7
- package/models/trace/handlers/PageLoadMetricsHandler.d.ts +67 -0
- package/models/trace/handlers/PageLoadMetricsHandler.js +357 -284
- package/models/trace/handlers/PageLoadMetricsHandler.js.map +1 -7
- package/models/trace/handlers/RendererHandler.d.ts +101 -0
- package/models/trace/handlers/RendererHandler.js +295 -191
- package/models/trace/handlers/RendererHandler.js.map +1 -7
- package/models/trace/handlers/SamplesHandler.d.ts +46 -0
- package/models/trace/handlers/SamplesHandler.js +195 -158
- package/models/trace/handlers/SamplesHandler.js.map +1 -7
- package/models/trace/handlers/ScreenshotsHandler.d.ts +7 -0
- package/models/trace/handlers/ScreenshotsHandler.js +63 -41
- package/models/trace/handlers/ScreenshotsHandler.js.map +1 -7
- package/models/trace/handlers/Threads.d.ts +33 -0
- package/models/trace/handlers/Threads.js +85 -67
- package/models/trace/handlers/Threads.js.map +1 -7
- package/models/trace/handlers/UserInteractionsHandler.d.ts +57 -0
- package/models/trace/handlers/UserInteractionsHandler.js +240 -141
- package/models/trace/handlers/UserInteractionsHandler.js.map +1 -7
- package/models/trace/handlers/UserTimingsHandler.d.ts +28 -0
- package/models/trace/handlers/UserTimingsHandler.js +91 -80
- package/models/trace/handlers/UserTimingsHandler.js.map +1 -7
- package/models/trace/handlers/WarningsHandler.d.ts +14 -0
- package/models/trace/handlers/WarningsHandler.js +100 -62
- package/models/trace/handlers/WarningsHandler.js.map +1 -7
- package/models/trace/handlers/WorkersHandler.d.ts +11 -0
- package/models/trace/handlers/WorkersHandler.js +40 -38
- package/models/trace/handlers/WorkersHandler.js.map +1 -7
- package/models/trace/handlers/handlers.d.ts +3 -0
- package/models/trace/handlers/handlers.js +7 -4
- package/models/trace/handlers/handlers.js.map +1 -7
- package/models/trace/handlers/types.d.ts +45 -0
- package/models/trace/handlers/types.js +15 -15
- package/models/trace/handlers/types.js.map +1 -7
- package/models/trace/helpers/SamplesIntegrator.d.ts +49 -0
- package/models/trace/helpers/SamplesIntegrator.js +381 -204
- package/models/trace/helpers/SamplesIntegrator.js.map +1 -7
- package/models/trace/helpers/Timing.d.ts +26 -0
- package/models/trace/helpers/Timing.js +131 -110
- package/models/trace/helpers/Timing.js.map +1 -7
- package/models/trace/helpers/Trace.d.ts +37 -0
- package/models/trace/helpers/Trace.js +200 -166
- package/models/trace/helpers/Trace.js.map +1 -7
- package/models/trace/helpers/TreeHelpers.d.ts +90 -0
- package/models/trace/helpers/TreeHelpers.js +203 -100
- package/models/trace/helpers/TreeHelpers.js.map +1 -7
- package/models/trace/helpers/helpers.d.ts +4 -0
- package/models/trace/helpers/helpers.js +8 -5
- package/models/trace/helpers/helpers.js.map +1 -7
- package/models/trace/root-causes/LayoutShift.d.ts +119 -0
- package/models/trace/root-causes/LayoutShift.js +470 -323
- package/models/trace/root-causes/LayoutShift.js.map +1 -7
- package/models/trace/root-causes/RootCauses.d.ts +14 -0
- package/models/trace/root-causes/RootCauses.js +9 -6
- package/models/trace/root-causes/RootCauses.js.map +1 -7
- package/models/trace/root-causes/root-causes.d.ts +1 -0
- package/models/trace/root-causes/root-causes.js +5 -2
- package/models/trace/root-causes/root-causes.js.map +1 -7
- package/models/trace/trace.d.ts +11 -0
- package/models/trace/trace.js +17 -23
- package/models/trace/trace.js.map +1 -7
- package/models/trace/types/Configuration.d.ts +33 -0
- package/models/trace/types/Configuration.js +25 -14
- package/models/trace/types/Configuration.js.map +1 -7
- package/models/trace/types/File.d.ts +23 -0
- package/models/trace/types/File.js +5 -6
- package/models/trace/types/File.js.map +1 -7
- package/models/trace/types/Timing.d.ts +25 -0
- package/models/trace/types/Timing.js +10 -11
- package/models/trace/types/Timing.js.map +1 -7
- package/models/trace/types/TraceEvents.d.ts +1571 -0
- package/models/trace/types/TraceEvents.js +174 -381
- package/models/trace/types/TraceEvents.js.map +1 -7
- package/models/trace/types/types.d.ts +4 -0
- package/models/trace/types/types.js +8 -5
- package/models/trace/types/types.js.map +1 -7
- package/package.json +1 -1
- package/TracingManager.js +0 -0
- package/extras/extras.js +0 -0
- package/trace.mjs +0 -6980
- package/trace.mjs.map +0 -8
|
@@ -1,7 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../../../../front_end/models/trace/handlers/ScreenshotsHandler.ts"],
|
|
4
|
-
"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 Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {type TraceEventHandlerName} from './types.js';\n\n// Each thread contains events. Events indicate the thread and process IDs, which are\n// used to store the event in the correct process thread entry below.\nconst unpairedAsyncEvents: Types.TraceEvents.TraceEventPipelineReporter[] = [];\n\nconst snapshotEvents: Types.TraceEvents.TraceEventScreenshot[] = [];\nconst syntheticScreenshotEvents: Types.TraceEvents.SyntheticScreenshot[] = [];\nlet frameSequenceToTs: Record<string, Types.Timing.MicroSeconds> = {};\n\nexport function reset(): void {\n unpairedAsyncEvents.length = 0;\n snapshotEvents.length = 0;\n syntheticScreenshotEvents.length = 0;\n frameSequenceToTs = {};\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (Types.TraceEvents.isTraceEventScreenshot(event)) {\n snapshotEvents.push(event);\n } else if (Types.TraceEvents.isTraceEventPipelineReporter(event)) {\n unpairedAsyncEvents.push(event);\n }\n}\n\nexport async function finalize(): Promise<void> {\n const pipelineReporterEvents = Helpers.Trace.createMatchedSortedSyntheticEvents(unpairedAsyncEvents);\n\n frameSequenceToTs = Object.fromEntries(pipelineReporterEvents.map(evt => {\n const frameSequenceId = evt.args.data.beginEvent.args.chrome_frame_reporter.frame_sequence;\n const presentationTs = Types.Timing.MicroSeconds(evt.ts + evt.dur);\n return [frameSequenceId, presentationTs];\n }));\n\n for (const snapshotEvent of snapshotEvents) {\n const {cat, name, ph, pid, tid} = snapshotEvent;\n const syntheticEvent: Types.TraceEvents.SyntheticScreenshot = {\n cat,\n name,\n ph,\n pid,\n tid,\n // `getPresentationTimestamp(snapshotEvent) - snapshotEvent.ts` is how many microsec the screenshot was adjusted to the right/later\n ts: getPresentationTimestamp(snapshotEvent),\n args: {\n dataUri: `data:image/jpg;base64,${snapshotEvent.args.snapshot}`,\n },\n };\n syntheticScreenshotEvents.push(syntheticEvent);\n }\n}\n\n/**\n * Correct the screenshot timestamps\n * The screenshot 'snapshot object' trace event has the \"frame sequence number\" attached as an ID.\n * We match that up with the \"PipelineReporter\" trace events as they terminate at presentation.\n * Presentation == when the pixels hit the screen. AKA Swap on the GPU\n */\nfunction getPresentationTimestamp(screenshotEvent: Types.TraceEvents.TraceEventScreenshot): Types.Timing.MicroSeconds {\n const frameSequence = parseInt(screenshotEvent.id, 16);\n // If it's 1, then it's an old trace (before https://crrev.com/c/4957973) and cannot be corrected.\n if (frameSequence === 1) {\n return screenshotEvent.ts;\n }\n // The screenshot trace event's `ts` reflects the \"expected display time\" which is ESTIMATE.\n // It is set by the compositor frame sink from the `expected_display_time`, which is based on a previously known\n // frame start PLUS the vsync interval (eg 16.6ms)\n const updatedTs = frameSequenceToTs[frameSequence];\n // Do we always find a match? No...\n // We generally don't match the very first screenshot and, sometimes, the last\n // The very first screenshot is requested immediately (even if nothing is painting). As a result there's no compositor\n // instrumentation running alongside.\n // The last one is sometimes missing as because the trace terminates right before the associated PipelineReporter is emitted.\n return updatedTs ?? screenshotEvent.ts;\n}\n\nexport function data(): Types.TraceEvents.SyntheticScreenshot[] {\n return [...syntheticScreenshotEvents];\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Meta'];\n}\n"],
|
|
5
|
-
"mappings": "AAIA;AACA;AAMA,MAAM,sBAAsE;AAE5E,MAAM,iBAA2D;AACjE,MAAM,4BAAqE;AAC3E,IAAI,oBAA+D;AAE5D,wBAAuB;AAC5B,sBAAoB,SAAS;AAC7B,iBAAe,SAAS;AACxB,4BAA0B,SAAS;AACnC,sBAAoB;AAAA;AAGf,4BAAqB,OAA+C;AACzE,MAAI,MAAM,YAAY,uBAAuB,QAAQ;AACnD,mBAAe,KAAK;AAAA,aACX,MAAM,YAAY,6BAA6B,QAAQ;AAChE,wBAAoB,KAAK;AAAA;AAAA;AAI7B,iCAAgD;AAC9C,QAAM,yBAAyB,QAAQ,MAAM,mCAAmC;AAEhF,sBAAoB,OAAO,YAAY,uBAAuB,IAAI,SAAO;AACvE,UAAM,kBAAkB,IAAI,KAAK,KAAK,WAAW,KAAK,sBAAsB;AAC5E,UAAM,iBAAiB,MAAM,OAAO,aAAa,IAAI,KAAK,IAAI;AAC9D,WAAO,CAAC,iBAAiB;AAAA;AAG3B,aAAW,iBAAiB,gBAAgB;AAC1C,UAAM,EAAC,KAAK,MAAM,IAAI,KAAK,QAAO;AAClC,UAAM,iBAAwD;AAAA,MAC5D;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAEA,IAAI,yBAAyB;AAAA,MAC7B,MAAM;AAAA,QACJ,SAAS,yBAAyB,cAAc,KAAK;AAAA;AAAA;AAGzD,8BAA0B,KAAK;AAAA;AAAA;AAUnC,kCAAkC,iBAAoF;AACpH,QAAM,gBAAgB,SAAS,gBAAgB,IAAI;AAEnD,MAAI,kBAAkB,GAAG;AACvB,WAAO,gBAAgB;AAAA;AAKzB,QAAM,YAAY,kBAAkB;AAMpC,SAAO,aAAa,gBAAgB;AAAA;AAG/B,uBAAyD;AAC9D,SAAO,CAAC,GAAG;AAAA;AAGN,uBAAyC;AAC9C,SAAO,CAAC;AAAA;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
1
|
+
{"version":3,"file":"ScreenshotsHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/ScreenshotsHandler.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 Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {type TraceEventHandlerName} from './types.js';\n\n// Each thread contains events. Events indicate the thread and process IDs, which are\n// used to store the event in the correct process thread entry below.\nconst unpairedAsyncEvents: Types.TraceEvents.TraceEventPipelineReporter[] = [];\n\nconst snapshotEvents: Types.TraceEvents.TraceEventScreenshot[] = [];\nconst syntheticScreenshotEvents: Types.TraceEvents.SyntheticScreenshot[] = [];\nlet frameSequenceToTs: Record<string, Types.Timing.MicroSeconds> = {};\n\nexport function reset(): void {\n unpairedAsyncEvents.length = 0;\n snapshotEvents.length = 0;\n syntheticScreenshotEvents.length = 0;\n frameSequenceToTs = {};\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (Types.TraceEvents.isTraceEventScreenshot(event)) {\n snapshotEvents.push(event);\n } else if (Types.TraceEvents.isTraceEventPipelineReporter(event)) {\n unpairedAsyncEvents.push(event);\n }\n}\n\nexport async function finalize(): Promise<void> {\n const pipelineReporterEvents = Helpers.Trace.createMatchedSortedSyntheticEvents(unpairedAsyncEvents);\n\n frameSequenceToTs = Object.fromEntries(pipelineReporterEvents.map(evt => {\n const frameSequenceId = evt.args.data.beginEvent.args.chrome_frame_reporter.frame_sequence;\n const presentationTs = Types.Timing.MicroSeconds(evt.ts + evt.dur);\n return [frameSequenceId, presentationTs];\n }));\n\n for (const snapshotEvent of snapshotEvents) {\n const {cat, name, ph, pid, tid} = snapshotEvent;\n const syntheticEvent: Types.TraceEvents.SyntheticScreenshot = {\n cat,\n name,\n ph,\n pid,\n tid,\n // `getPresentationTimestamp(snapshotEvent) - snapshotEvent.ts` is how many microsec the screenshot was adjusted to the right/later\n ts: getPresentationTimestamp(snapshotEvent),\n args: {\n dataUri: `data:image/jpg;base64,${snapshotEvent.args.snapshot}`,\n },\n };\n syntheticScreenshotEvents.push(syntheticEvent);\n }\n}\n\n/**\n * Correct the screenshot timestamps\n * The screenshot 'snapshot object' trace event has the \"frame sequence number\" attached as an ID.\n * We match that up with the \"PipelineReporter\" trace events as they terminate at presentation.\n * Presentation == when the pixels hit the screen. AKA Swap on the GPU\n */\nfunction getPresentationTimestamp(screenshotEvent: Types.TraceEvents.TraceEventScreenshot): Types.Timing.MicroSeconds {\n const frameSequence = parseInt(screenshotEvent.id, 16);\n // If it's 1, then it's an old trace (before https://crrev.com/c/4957973) and cannot be corrected.\n if (frameSequence === 1) {\n return screenshotEvent.ts;\n }\n // The screenshot trace event's `ts` reflects the \"expected display time\" which is ESTIMATE.\n // It is set by the compositor frame sink from the `expected_display_time`, which is based on a previously known\n // frame start PLUS the vsync interval (eg 16.6ms)\n const updatedTs = frameSequenceToTs[frameSequence];\n // Do we always find a match? No...\n // We generally don't match the very first screenshot and, sometimes, the last\n // The very first screenshot is requested immediately (even if nothing is painting). As a result there's no compositor\n // instrumentation running alongside.\n // The last one is sometimes missing as because the trace terminates right before the associated PipelineReporter is emitted.\n return updatedTs ?? screenshotEvent.ts;\n}\n\nexport function data(): Types.TraceEvents.SyntheticScreenshot[] {\n return [...syntheticScreenshotEvents];\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Meta'];\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type * as Helpers from '../helpers/helpers.js';
|
|
2
|
+
import type * as Types from '../types/types.js';
|
|
3
|
+
import { type AuctionWorkletsData } from './AuctionWorkletsHandler.js';
|
|
4
|
+
import type * as Renderer from './RendererHandler.js';
|
|
5
|
+
import { type TraceParseData } from './types.js';
|
|
6
|
+
export interface ThreadData {
|
|
7
|
+
pid: Types.TraceEvents.ProcessID;
|
|
8
|
+
tid: Types.TraceEvents.ThreadID;
|
|
9
|
+
entries: readonly Types.TraceEvents.SyntheticTraceEntry[];
|
|
10
|
+
processIsOnMainFrame: boolean;
|
|
11
|
+
tree: Helpers.TreeHelpers.TraceEntryTree;
|
|
12
|
+
type: ThreadType;
|
|
13
|
+
name: string | null;
|
|
14
|
+
entryToNode: Map<Types.TraceEvents.SyntheticTraceEntry, Helpers.TreeHelpers.TraceEntryNode>;
|
|
15
|
+
}
|
|
16
|
+
export declare const enum ThreadType {
|
|
17
|
+
MAIN_THREAD = "MAIN_THREAD",
|
|
18
|
+
WORKER = "WORKER",
|
|
19
|
+
RASTERIZER = "RASTERIZER",
|
|
20
|
+
AUCTION_WORKLET = "AUCTION_WORKLET",
|
|
21
|
+
OTHER = "OTHER",
|
|
22
|
+
CPU_PROFILE = "CPU_PROFILE",
|
|
23
|
+
THREAD_POOL = "THREAD_POOL"
|
|
24
|
+
}
|
|
25
|
+
export declare function threadsInRenderer(rendererData: Renderer.RendererHandlerData, auctionWorkletsData: AuctionWorkletsData): readonly ThreadData[];
|
|
26
|
+
/**
|
|
27
|
+
* Given trace parsed data, this helper will return a high level array of
|
|
28
|
+
* ThreadData. This is useful because it allows you to get a list of threads
|
|
29
|
+
* regardless of if the trace is a CPU Profile or a Tracing profile. Thus you
|
|
30
|
+
* can use this helper to iterate over threads in confidence that it will work
|
|
31
|
+
* for both trace types.
|
|
32
|
+
*/
|
|
33
|
+
export declare function threadsInTrace(traceParseData: TraceParseData): readonly ThreadData[];
|
|
@@ -1,77 +1,95 @@
|
|
|
1
|
-
export var ThreadType = /* @__PURE__ */ ((ThreadType2) => {
|
|
2
|
-
ThreadType2["MAIN_THREAD"] = "MAIN_THREAD";
|
|
3
|
-
ThreadType2["WORKER"] = "WORKER";
|
|
4
|
-
ThreadType2["RASTERIZER"] = "RASTERIZER";
|
|
5
|
-
ThreadType2["AUCTION_WORKLET"] = "AUCTION_WORKLET";
|
|
6
|
-
ThreadType2["OTHER"] = "OTHER";
|
|
7
|
-
ThreadType2["CPU_PROFILE"] = "CPU_PROFILE";
|
|
8
|
-
ThreadType2["THREAD_POOL"] = "THREAD_POOL";
|
|
9
|
-
return ThreadType2;
|
|
10
|
-
})(ThreadType || {});
|
|
11
1
|
function getThreadTypeForRendererThread(auctionWorkletsData, pid, thread) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
2
|
+
let threadType = "OTHER" /* ThreadType.OTHER */;
|
|
3
|
+
if (thread.name === 'CrRendererMain') {
|
|
4
|
+
threadType = "MAIN_THREAD" /* ThreadType.MAIN_THREAD */;
|
|
5
|
+
}
|
|
6
|
+
else if (thread.name === 'DedicatedWorker thread') {
|
|
7
|
+
threadType = "WORKER" /* ThreadType.WORKER */;
|
|
8
|
+
}
|
|
9
|
+
else if (thread.name?.startsWith('CompositorTileWorker')) {
|
|
10
|
+
threadType = "RASTERIZER" /* ThreadType.RASTERIZER */;
|
|
11
|
+
}
|
|
12
|
+
else if (auctionWorkletsData.worklets.has(pid)) {
|
|
13
|
+
threadType = "AUCTION_WORKLET" /* ThreadType.AUCTION_WORKLET */;
|
|
14
|
+
}
|
|
15
|
+
else if (thread.name?.startsWith('ThreadPool')) {
|
|
16
|
+
// TODO(paulirish): perhaps exclude ThreadPoolServiceThread entirely
|
|
17
|
+
threadType = "THREAD_POOL" /* ThreadType.THREAD_POOL */;
|
|
18
|
+
}
|
|
19
|
+
return threadType;
|
|
25
20
|
}
|
|
26
21
|
export function threadsInRenderer(rendererData, auctionWorkletsData) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
const foundThreads = [];
|
|
23
|
+
// If we have Renderer threads, we prefer to use those. In the event that a
|
|
24
|
+
// trace is a CPU Profile trace, we will never have Renderer threads, so we
|
|
25
|
+
// know if there are no Renderer threads that we can fallback to using the
|
|
26
|
+
// data from the SamplesHandler.
|
|
27
|
+
if (rendererData.processes.size) {
|
|
28
|
+
for (const [pid, process] of rendererData.processes) {
|
|
29
|
+
for (const [tid, thread] of process.threads) {
|
|
30
|
+
if (!thread.tree) {
|
|
31
|
+
// Drop threads where we could not create the tree; this indicates
|
|
32
|
+
// unexpected data and we won't be able to support all the UI
|
|
33
|
+
// filtering we need.
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const threadType = getThreadTypeForRendererThread(auctionWorkletsData, pid, thread);
|
|
37
|
+
foundThreads.push({
|
|
38
|
+
name: thread.name,
|
|
39
|
+
pid,
|
|
40
|
+
tid,
|
|
41
|
+
processIsOnMainFrame: process.isOnMainFrame,
|
|
42
|
+
entries: thread.entries,
|
|
43
|
+
tree: thread.tree,
|
|
44
|
+
type: threadType,
|
|
45
|
+
entryToNode: rendererData.entryToNode,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
33
48
|
}
|
|
34
|
-
const threadType = getThreadTypeForRendererThread(auctionWorkletsData, pid, thread);
|
|
35
|
-
foundThreads.push({
|
|
36
|
-
name: thread.name,
|
|
37
|
-
pid,
|
|
38
|
-
tid,
|
|
39
|
-
processIsOnMainFrame: process.isOnMainFrame,
|
|
40
|
-
entries: thread.entries,
|
|
41
|
-
tree: thread.tree,
|
|
42
|
-
type: threadType,
|
|
43
|
-
entryToNode: rendererData.entryToNode
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
49
|
}
|
|
47
|
-
|
|
48
|
-
return foundThreads;
|
|
50
|
+
return foundThreads;
|
|
49
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Given trace parsed data, this helper will return a high level array of
|
|
54
|
+
* ThreadData. This is useful because it allows you to get a list of threads
|
|
55
|
+
* regardless of if the trace is a CPU Profile or a Tracing profile. Thus you
|
|
56
|
+
* can use this helper to iterate over threads in confidence that it will work
|
|
57
|
+
* for both trace types.
|
|
58
|
+
*/
|
|
50
59
|
export function threadsInTrace(traceParseData) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
// If we have Renderer threads, we prefer to use those. In the event that a
|
|
61
|
+
// trace is a CPU Profile trace, we will never have Renderer threads, so we
|
|
62
|
+
// know if there are no Renderer threads that we can fallback to using the
|
|
63
|
+
// data from the SamplesHandler.
|
|
64
|
+
const threadsFromRenderer = threadsInRenderer(traceParseData.Renderer, traceParseData.AuctionWorklets);
|
|
65
|
+
if (threadsFromRenderer.length) {
|
|
66
|
+
return threadsFromRenderer;
|
|
67
|
+
}
|
|
68
|
+
const foundThreads = [];
|
|
69
|
+
if (traceParseData.Samples.profilesInProcess.size) {
|
|
70
|
+
for (const [pid, process] of traceParseData.Samples.profilesInProcess) {
|
|
71
|
+
for (const [tid, thread] of process) {
|
|
72
|
+
if (!thread.profileTree) {
|
|
73
|
+
// Drop threads where we could not create the tree; this indicates
|
|
74
|
+
// unexpected data and we won't be able to support all the UI
|
|
75
|
+
// filtering we need.
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
foundThreads.push({
|
|
79
|
+
pid,
|
|
80
|
+
tid,
|
|
81
|
+
// CPU Profile threads do not have a name.
|
|
82
|
+
name: null,
|
|
83
|
+
entries: thread.profileCalls,
|
|
84
|
+
// There is no concept of a "Main Frame" in a CPU profile.
|
|
85
|
+
processIsOnMainFrame: false,
|
|
86
|
+
tree: thread.profileTree,
|
|
87
|
+
type: "CPU_PROFILE" /* ThreadType.CPU_PROFILE */,
|
|
88
|
+
entryToNode: traceParseData.Samples.entryToNode,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
61
91
|
}
|
|
62
|
-
foundThreads.push({
|
|
63
|
-
pid,
|
|
64
|
-
tid,
|
|
65
|
-
name: null,
|
|
66
|
-
entries: thread.profileCalls,
|
|
67
|
-
processIsOnMainFrame: false,
|
|
68
|
-
tree: thread.profileTree,
|
|
69
|
-
type: "CPU_PROFILE" /* CPU_PROFILE */,
|
|
70
|
-
entryToNode: traceParseData.Samples.entryToNode
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
92
|
}
|
|
74
|
-
|
|
75
|
-
return foundThreads;
|
|
93
|
+
return foundThreads;
|
|
76
94
|
}
|
|
77
|
-
//# sourceMappingURL=Threads.js.map
|
|
95
|
+
//# sourceMappingURL=Threads.js.map
|
|
@@ -1,7 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../../../../front_end/models/trace/handlers/Threads.ts"],
|
|
4
|
-
"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 type * as Helpers from '../helpers/helpers.js';\nimport type * as Types from '../types/types.js';\n\nimport {type AuctionWorkletsData} from './AuctionWorkletsHandler.js';\nimport type * as Renderer from './RendererHandler.js';\nimport {type TraceParseData} from './types.js';\n\nexport interface ThreadData {\n pid: Types.TraceEvents.ProcessID;\n tid: Types.TraceEvents.ThreadID;\n entries: readonly Types.TraceEvents.SyntheticTraceEntry[];\n processIsOnMainFrame: boolean;\n tree: Helpers.TreeHelpers.TraceEntryTree;\n type: ThreadType;\n name: string|null;\n entryToNode: Map<Types.TraceEvents.SyntheticTraceEntry, Helpers.TreeHelpers.TraceEntryNode>;\n}\n\nexport const enum ThreadType {\n MAIN_THREAD = 'MAIN_THREAD',\n WORKER = 'WORKER',\n RASTERIZER = 'RASTERIZER',\n AUCTION_WORKLET = 'AUCTION_WORKLET',\n OTHER = 'OTHER',\n CPU_PROFILE = 'CPU_PROFILE',\n THREAD_POOL = 'THREAD_POOL',\n}\n\nfunction getThreadTypeForRendererThread(\n auctionWorkletsData: AuctionWorkletsData, pid: Types.TraceEvents.ProcessID,\n thread: Renderer.RendererThread): ThreadType {\n let threadType = ThreadType.OTHER;\n if (thread.name === 'CrRendererMain') {\n threadType = ThreadType.MAIN_THREAD;\n } else if (thread.name === 'DedicatedWorker thread') {\n threadType = ThreadType.WORKER;\n } else if (thread.name?.startsWith('CompositorTileWorker')) {\n threadType = ThreadType.RASTERIZER;\n } else if (auctionWorkletsData.worklets.has(pid)) {\n threadType = ThreadType.AUCTION_WORKLET;\n } else if (thread.name?.startsWith('ThreadPool')) {\n // TODO(paulirish): perhaps exclude ThreadPoolServiceThread entirely\n threadType = ThreadType.THREAD_POOL;\n }\n return threadType;\n}\n\nexport function threadsInRenderer(\n rendererData: Renderer.RendererHandlerData, auctionWorkletsData: AuctionWorkletsData): readonly ThreadData[] {\n const foundThreads: ThreadData[] = [];\n // If we have Renderer threads, we prefer to use those. In the event that a\n // trace is a CPU Profile trace, we will never have Renderer threads, so we\n // know if there are no Renderer threads that we can fallback to using the\n // data from the SamplesHandler.\n if (rendererData.processes.size) {\n for (const [pid, process] of rendererData.processes) {\n for (const [tid, thread] of process.threads) {\n if (!thread.tree) {\n // Drop threads where we could not create the tree; this indicates\n // unexpected data and we won't be able to support all the UI\n // filtering we need.\n continue;\n }\n const threadType = getThreadTypeForRendererThread(auctionWorkletsData, pid, thread);\n foundThreads.push({\n name: thread.name,\n pid,\n tid,\n processIsOnMainFrame: process.isOnMainFrame,\n entries: thread.entries,\n tree: thread.tree,\n type: threadType,\n entryToNode: rendererData.entryToNode,\n });\n }\n }\n }\n return foundThreads;\n}\n\n/**\n * Given trace parsed data, this helper will return a high level array of\n * ThreadData. This is useful because it allows you to get a list of threads\n * regardless of if the trace is a CPU Profile or a Tracing profile. Thus you\n * can use this helper to iterate over threads in confidence that it will work\n * for both trace types.\n */\nexport function threadsInTrace(traceParseData: TraceParseData): readonly ThreadData[] {\n // If we have Renderer threads, we prefer to use those. In the event that a\n // trace is a CPU Profile trace, we will never have Renderer threads, so we\n // know if there are no Renderer threads that we can fallback to using the\n // data from the SamplesHandler.\n const threadsFromRenderer = threadsInRenderer(traceParseData.Renderer, traceParseData.AuctionWorklets);\n if (threadsFromRenderer.length) {\n return threadsFromRenderer;\n }\n\n const foundThreads: ThreadData[] = [];\n if (traceParseData.Samples.profilesInProcess.size) {\n for (const [pid, process] of traceParseData.Samples.profilesInProcess) {\n for (const [tid, thread] of process) {\n if (!thread.profileTree) {\n // Drop threads where we could not create the tree; this indicates\n // unexpected data and we won't be able to support all the UI\n // filtering we need.\n continue;\n }\n\n foundThreads.push({\n pid,\n tid,\n // CPU Profile threads do not have a name.\n name: null,\n entries: thread.profileCalls,\n // There is no concept of a \"Main Frame\" in a CPU profile.\n processIsOnMainFrame: false,\n tree: thread.profileTree,\n type: ThreadType.CPU_PROFILE,\n entryToNode: traceParseData.Samples.entryToNode,\n });\n }\n }\n }\n\n return foundThreads;\n}\n"],
|
|
5
|
-
"mappings": "AAsBO,WAAW,aAAX,kBAAW,gBAAX;AACL,+BAAc;AACd,0BAAS;AACT,8BAAa;AACb,mCAAkB;AAClB,yBAAQ;AACR,+BAAc;AACd,+BAAc;AAPE;AAAA;AAUlB,wCACI,qBAA0C,KAC1C,QAA6C;AAC/C,MAAI,aAAa;AACjB,MAAI,OAAO,SAAS,kBAAkB;AACpC,iBAAa;AAAA,aACJ,OAAO,SAAS,0BAA0B;AACnD,iBAAa;AAAA,aACJ,OAAO,MAAM,WAAW,yBAAyB;AAC1D,iBAAa;AAAA,aACJ,oBAAoB,SAAS,IAAI,MAAM;AAChD,iBAAa;AAAA,aACJ,OAAO,MAAM,WAAW,eAAe;AAEhD,iBAAa;AAAA;AAEf,SAAO;AAAA;AAGF,kCACH,cAA4C,qBAAiE;AAC/G,QAAM,eAA6B;AAKnC,MAAI,aAAa,UAAU,MAAM;AAC/B,eAAW,CAAC,KAAK,YAAY,aAAa,WAAW;AACnD,iBAAW,CAAC,KAAK,WAAW,QAAQ,SAAS;AAC3C,YAAI,CAAC,OAAO,MAAM;AAIhB;AAAA;AAEF,cAAM,aAAa,+BAA+B,qBAAqB,KAAK;AAC5E,qBAAa,KAAK;AAAA,UAChB,MAAM,OAAO;AAAA,UACb;AAAA,UACA;AAAA,UACA,sBAAsB,QAAQ;AAAA,UAC9B,SAAS,OAAO;AAAA,UAChB,MAAM,OAAO;AAAA,UACb,MAAM;AAAA,UACN,aAAa,aAAa;AAAA;AAAA;AAAA;AAAA;AAKlC,SAAO;AAAA;AAUF,+BAAwB,gBAAuD;AAKpF,QAAM,sBAAsB,kBAAkB,eAAe,UAAU,eAAe;AACtF,MAAI,oBAAoB,QAAQ;AAC9B,WAAO;AAAA;AAGT,QAAM,eAA6B;AACnC,MAAI,eAAe,QAAQ,kBAAkB,MAAM;AACjD,eAAW,CAAC,KAAK,YAAY,eAAe,QAAQ,mBAAmB;AACrE,iBAAW,CAAC,KAAK,WAAW,SAAS;AACnC,YAAI,CAAC,OAAO,aAAa;AAIvB;AAAA;AAGF,qBAAa,KAAK;AAAA,UAChB;AAAA,UACA;AAAA,UAEA,MAAM;AAAA,UACN,SAAS,OAAO;AAAA,UAEhB,sBAAsB;AAAA,UACtB,MAAM,OAAO;AAAA,UACb,MAAM;AAAA,UACN,aAAa,eAAe,QAAQ;AAAA;AAAA;AAAA;AAAA;AAM5C,SAAO;AAAA;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
1
|
+
{"version":3,"file":"Threads.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/Threads.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 type * as Helpers from '../helpers/helpers.js';\nimport type * as Types from '../types/types.js';\n\nimport {type AuctionWorkletsData} from './AuctionWorkletsHandler.js';\nimport type * as Renderer from './RendererHandler.js';\nimport {type TraceParseData} from './types.js';\n\nexport interface ThreadData {\n pid: Types.TraceEvents.ProcessID;\n tid: Types.TraceEvents.ThreadID;\n entries: readonly Types.TraceEvents.SyntheticTraceEntry[];\n processIsOnMainFrame: boolean;\n tree: Helpers.TreeHelpers.TraceEntryTree;\n type: ThreadType;\n name: string|null;\n entryToNode: Map<Types.TraceEvents.SyntheticTraceEntry, Helpers.TreeHelpers.TraceEntryNode>;\n}\n\nexport const enum ThreadType {\n MAIN_THREAD = 'MAIN_THREAD',\n WORKER = 'WORKER',\n RASTERIZER = 'RASTERIZER',\n AUCTION_WORKLET = 'AUCTION_WORKLET',\n OTHER = 'OTHER',\n CPU_PROFILE = 'CPU_PROFILE',\n THREAD_POOL = 'THREAD_POOL',\n}\n\nfunction getThreadTypeForRendererThread(\n auctionWorkletsData: AuctionWorkletsData, pid: Types.TraceEvents.ProcessID,\n thread: Renderer.RendererThread): ThreadType {\n let threadType = ThreadType.OTHER;\n if (thread.name === 'CrRendererMain') {\n threadType = ThreadType.MAIN_THREAD;\n } else if (thread.name === 'DedicatedWorker thread') {\n threadType = ThreadType.WORKER;\n } else if (thread.name?.startsWith('CompositorTileWorker')) {\n threadType = ThreadType.RASTERIZER;\n } else if (auctionWorkletsData.worklets.has(pid)) {\n threadType = ThreadType.AUCTION_WORKLET;\n } else if (thread.name?.startsWith('ThreadPool')) {\n // TODO(paulirish): perhaps exclude ThreadPoolServiceThread entirely\n threadType = ThreadType.THREAD_POOL;\n }\n return threadType;\n}\n\nexport function threadsInRenderer(\n rendererData: Renderer.RendererHandlerData, auctionWorkletsData: AuctionWorkletsData): readonly ThreadData[] {\n const foundThreads: ThreadData[] = [];\n // If we have Renderer threads, we prefer to use those. In the event that a\n // trace is a CPU Profile trace, we will never have Renderer threads, so we\n // know if there are no Renderer threads that we can fallback to using the\n // data from the SamplesHandler.\n if (rendererData.processes.size) {\n for (const [pid, process] of rendererData.processes) {\n for (const [tid, thread] of process.threads) {\n if (!thread.tree) {\n // Drop threads where we could not create the tree; this indicates\n // unexpected data and we won't be able to support all the UI\n // filtering we need.\n continue;\n }\n const threadType = getThreadTypeForRendererThread(auctionWorkletsData, pid, thread);\n foundThreads.push({\n name: thread.name,\n pid,\n tid,\n processIsOnMainFrame: process.isOnMainFrame,\n entries: thread.entries,\n tree: thread.tree,\n type: threadType,\n entryToNode: rendererData.entryToNode,\n });\n }\n }\n }\n return foundThreads;\n}\n\n/**\n * Given trace parsed data, this helper will return a high level array of\n * ThreadData. This is useful because it allows you to get a list of threads\n * regardless of if the trace is a CPU Profile or a Tracing profile. Thus you\n * can use this helper to iterate over threads in confidence that it will work\n * for both trace types.\n */\nexport function threadsInTrace(traceParseData: TraceParseData): readonly ThreadData[] {\n // If we have Renderer threads, we prefer to use those. In the event that a\n // trace is a CPU Profile trace, we will never have Renderer threads, so we\n // know if there are no Renderer threads that we can fallback to using the\n // data from the SamplesHandler.\n const threadsFromRenderer = threadsInRenderer(traceParseData.Renderer, traceParseData.AuctionWorklets);\n if (threadsFromRenderer.length) {\n return threadsFromRenderer;\n }\n\n const foundThreads: ThreadData[] = [];\n if (traceParseData.Samples.profilesInProcess.size) {\n for (const [pid, process] of traceParseData.Samples.profilesInProcess) {\n for (const [tid, thread] of process) {\n if (!thread.profileTree) {\n // Drop threads where we could not create the tree; this indicates\n // unexpected data and we won't be able to support all the UI\n // filtering we need.\n continue;\n }\n\n foundThreads.push({\n pid,\n tid,\n // CPU Profile threads do not have a name.\n name: null,\n entries: thread.profileCalls,\n // There is no concept of a \"Main Frame\" in a CPU profile.\n processIsOnMainFrame: false,\n tree: thread.profileTree,\n type: ThreadType.CPU_PROFILE,\n entryToNode: traceParseData.Samples.entryToNode,\n });\n }\n }\n }\n\n return foundThreads;\n}\n"]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as Types from '../types/types.js';
|
|
2
|
+
export declare const LONG_INTERACTION_THRESHOLD: Types.Timing.MicroSeconds;
|
|
3
|
+
export interface UserInteractionsData {
|
|
4
|
+
/** All the user events we found in the trace */
|
|
5
|
+
allEvents: readonly Types.TraceEvents.TraceEventEventTiming[];
|
|
6
|
+
/** All the interaction events we found in the trace that had an
|
|
7
|
+
* interactionId and a duration > 0
|
|
8
|
+
**/
|
|
9
|
+
interactionEvents: readonly Types.TraceEvents.SyntheticInteractionPair[];
|
|
10
|
+
/** If the user rapidly generates interaction events (think typing into a
|
|
11
|
+
* text box), in the UI we only really want to show the user the longest
|
|
12
|
+
* interaction in that set.
|
|
13
|
+
* For example picture interactions like this:
|
|
14
|
+
* ===[interaction A]==========
|
|
15
|
+
* =[interaction B]======
|
|
16
|
+
* =[interaction C]=
|
|
17
|
+
*
|
|
18
|
+
* These events all end at the same time, and so in this instance we only want
|
|
19
|
+
* to show the first interaction A on the timeline, as that is the longest one
|
|
20
|
+
* and the one the developer should be focusing on. So this array of events is
|
|
21
|
+
* all the interaction events filtered down, removing any nested interactions
|
|
22
|
+
* entirely.
|
|
23
|
+
**/
|
|
24
|
+
interactionEventsWithNoNesting: readonly Types.TraceEvents.SyntheticInteractionPair[];
|
|
25
|
+
longestInteractionEvent: Readonly<Types.TraceEvents.SyntheticInteractionPair> | null;
|
|
26
|
+
interactionsOverThreshold: Readonly<Set<Types.TraceEvents.SyntheticInteractionPair>>;
|
|
27
|
+
}
|
|
28
|
+
export declare function reset(): void;
|
|
29
|
+
export declare function handleEvent(event: Types.TraceEvents.TraceEventData): void;
|
|
30
|
+
export type InteractionCategory = 'KEYBOARD' | 'POINTER' | 'OTHER';
|
|
31
|
+
export declare function categoryOfInteraction(interaction: Types.TraceEvents.SyntheticInteractionPair): InteractionCategory;
|
|
32
|
+
/**
|
|
33
|
+
* We define a set of interactions as nested where:
|
|
34
|
+
* 1. Their end times align.
|
|
35
|
+
* 2. The longest interaction's start time is earlier than all other
|
|
36
|
+
* interactions with the same end time.
|
|
37
|
+
* 3. The interactions are of the same category [each interaction is either
|
|
38
|
+
* categorised as keyboard, or pointer.]
|
|
39
|
+
*
|
|
40
|
+
* =============A=[pointerup]=
|
|
41
|
+
* ====B=[pointerdown]=
|
|
42
|
+
* ===C=[pointerdown]==
|
|
43
|
+
* ===D=[pointerup]===
|
|
44
|
+
*
|
|
45
|
+
* In this example, B, C and D are all nested and therefore should not be
|
|
46
|
+
* returned from this function.
|
|
47
|
+
*
|
|
48
|
+
* However, in this example we would only consider B nested (under A) and D
|
|
49
|
+
* nested (under C). A and C both stay because they are of different types.
|
|
50
|
+
* ========A=[keydown]====
|
|
51
|
+
* =======B=[keyup]=====
|
|
52
|
+
* ====C=[pointerdown]=
|
|
53
|
+
* =D=[pointerup]=
|
|
54
|
+
**/
|
|
55
|
+
export declare function removeNestedInteractions(interactions: readonly Types.TraceEvents.SyntheticInteractionPair[]): readonly Types.TraceEvents.SyntheticInteractionPair[];
|
|
56
|
+
export declare function finalize(): Promise<void>;
|
|
57
|
+
export declare function data(): UserInteractionsData;
|