@paulirish/trace_engine 0.0.9 → 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 +23 -0
- package/core/platform/DevToolsPath.js +7 -0
- package/core/platform/DevToolsPath.js.map +1 -0
- package/core/platform/MimeType.d.ts +27 -0
- package/core/platform/MimeType.js +137 -0
- package/core/platform/MimeType.js.map +1 -0
- package/core/platform/Timing.d.ts +7 -0
- package/core/platform/Timing.js +13 -0
- package/core/platform/Timing.js.map +1 -0
- package/core/platform/UIString.d.ts +3 -0
- package/core/platform/UIString.js +5 -0
- package/core/platform/UIString.js.map +1 -0
- package/core/platform/UserVisibleError.d.ts +12 -0
- package/core/platform/UserVisibleError.js +23 -0
- package/core/platform/UserVisibleError.js.map +1 -0
- package/core/platform/array-utilities.d.ts +66 -0
- package/core/platform/array-utilities.js +199 -0
- package/core/platform/array-utilities.js.map +1 -0
- package/core/platform/brand.d.ts +14 -0
- package/core/platform/brand.js +5 -0
- package/core/platform/brand.js.map +1 -0
- package/core/platform/bundle-tsconfig.json +1 -0
- package/core/platform/date-utilities.d.ts +2 -0
- package/core/platform/date-utilities.js +14 -0
- package/core/platform/date-utilities.js.map +1 -0
- package/core/platform/dcheck-tsconfig.json +8 -0
- package/core/platform/dcheck.d.ts +4 -0
- package/core/platform/dcheck.js +5 -0
- package/core/platform/devtools_entrypoint-bundle-tsconfig-tsconfig.json +40 -0
- package/core/platform/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
- package/core/platform/dom-utilities.d.ts +8 -0
- package/core/platform/dom-utilities.js +109 -0
- package/core/platform/dom-utilities.js.map +1 -0
- package/core/platform/keyboard-utilities.d.ts +17 -0
- package/core/platform/keyboard-utilities.js +22 -0
- package/core/platform/keyboard-utilities.js.map +1 -0
- package/core/platform/map-utilities.d.ts +18 -0
- package/core/platform/map-utilities.js +76 -0
- package/core/platform/map-utilities.js.map +1 -0
- package/core/platform/number-utilities.d.ts +15 -0
- package/core/platform/number-utilities.js +82 -0
- package/core/platform/number-utilities.js.map +1 -0
- package/core/platform/platform-tsconfig.json +59 -0
- package/core/platform/platform.d.ts +19 -0
- package/core/platform/platform.js +54 -0
- package/core/platform/platform.js.compressed +0 -0
- package/core/platform/platform.js.hash +1 -0
- package/core/platform/platform.js.map +1 -0
- package/core/platform/platform.prebundle.d.ts +15 -0
- package/core/platform/platform.prebundle.js +50 -0
- package/core/platform/platform.prebundle.js.map +1 -0
- package/core/platform/platform.prebundle.ts +64 -0
- package/core/platform/promise-utilities.d.ts +10 -0
- package/core/platform/promise-utilities.js +18 -0
- package/core/platform/promise-utilities.js.map +1 -0
- package/core/platform/set-utilities.d.ts +2 -0
- package/core/platform/set-utilities.js +23 -0
- package/core/platform/set-utilities.js.map +1 -0
- package/core/platform/string-utilities.d.ts +71 -0
- package/core/platform/string-utilities.js +513 -0
- package/core/platform/string-utilities.js.map +1 -0
- package/core/platform/typescript-utilities.d.ts +56 -0
- package/core/platform/typescript-utilities.js +25 -0
- package/core/platform/typescript-utilities.js.map +1 -0
- package/generated/protocol.d.ts +17923 -0
- package/generated/protocol.js +5 -0
- package/models/cpu_profile/CPUProfileDataModel.d.ts +77 -0
- package/models/cpu_profile/CPUProfileDataModel.js +508 -0
- package/models/cpu_profile/CPUProfileDataModel.js.map +1 -0
- package/models/cpu_profile/ProfileTreeModel.d.ts +29 -0
- package/models/cpu_profile/ProfileTreeModel.js +95 -0
- package/models/cpu_profile/ProfileTreeModel.js.map +1 -0
- package/models/cpu_profile/bundle-tsconfig.json +1 -0
- package/models/cpu_profile/cpu_profile-tsconfig.json +51 -0
- package/models/cpu_profile/cpu_profile.d.ts +3 -0
- package/models/cpu_profile/cpu_profile.js +7 -0
- package/models/cpu_profile/cpu_profile.js.map +1 -0
- package/models/cpu_profile/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
- package/models/trace/EntriesFilter.d.ts +55 -0
- package/models/trace/EntriesFilter.js +243 -0
- package/models/trace/EntriesFilter.js.map +1 -0
- package/models/trace/LegacyTracingModel.d.ts +1 -0
- package/models/trace/LegacyTracingModel.js +1 -0
- package/models/trace/LegacyTracingModel.js.map +1 -0
- package/models/trace/ModelImpl.d.ts +110 -0
- package/models/trace/ModelImpl.js +175 -0
- package/models/trace/ModelImpl.js.map +1 -0
- package/models/trace/Processor.d.ts +36 -0
- package/models/trace/Processor.js +213 -0
- package/models/trace/Processor.js.map +1 -0
- package/models/trace/SDKServices.js +104 -0
- package/models/trace/SDKServices.js.map +7 -0
- package/models/trace/TraceProcessor.js +133 -0
- package/models/trace/TraceProcessor.js.map +7 -0
- package/models/trace/TracingManager.d.ts +1 -0
- package/models/trace/TracingManager.js +1 -0
- package/models/trace/TracingManager.js.map +1 -0
- package/models/trace/TreeManipulator.js +85 -0
- package/models/trace/TreeManipulator.js.map +7 -0
- package/models/trace/bundle-tsconfig.json +1 -0
- package/models/trace/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
- package/models/trace/devtools_entrypoint-legacy-typescript-tsconfig.json +43 -0
- package/models/trace/extras/FetchNodes.d.ts +46 -0
- package/models/trace/extras/FetchNodes.js +145 -0
- package/models/trace/extras/FetchNodes.js.map +1 -0
- package/models/trace/extras/FilmStrip.d.ts +19 -0
- package/models/trace/extras/FilmStrip.js +44 -0
- package/models/trace/extras/FilmStrip.js.map +1 -0
- package/models/trace/extras/MainThreadActivity.d.ts +2 -0
- package/models/trace/extras/MainThreadActivity.js +77 -0
- package/models/trace/extras/MainThreadActivity.js.map +1 -0
- package/models/trace/extras/Metadata.d.ts +2 -0
- package/models/trace/extras/Metadata.js +44 -0
- package/models/trace/extras/Metadata.js.map +1 -0
- package/models/trace/extras/bundle-tsconfig.json +1 -0
- package/models/trace/extras/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
- package/models/trace/extras/extras-tsconfig.json +59 -0
- package/models/trace/extras/extras.d.ts +1 -0
- package/models/trace/extras/extras.js +1 -0
- package/models/trace/extras/extras.js.map +1 -0
- package/models/trace/frames/TimelineFrameModel.js +392 -0
- package/models/trace/frames/TimelineFrameModel.js.map +7 -0
- package/models/trace/frames/bundle-tsconfig.json +1 -0
- package/models/trace/frames/devtools_entrypoint-bundle-typescript-tsconfig.json +43 -0
- package/models/trace/frames/frames-tsconfig.json +58 -0
- package/models/trace/frames/frames.js +5 -0
- package/models/trace/frames/frames.js.map +7 -0
- package/models/trace/handlers/AnimationHandler.d.ts +8 -0
- package/models/trace/handlers/AnimationHandler.js +32 -0
- package/models/trace/handlers/AnimationHandler.js.map +1 -0
- package/models/trace/handlers/AuctionWorkletsHandler.d.ts +8 -0
- package/models/trace/handlers/AuctionWorkletsHandler.js +160 -0
- package/models/trace/handlers/AuctionWorkletsHandler.js.map +1 -0
- package/models/trace/handlers/FramesHandler.d.ts +76 -0
- package/models/trace/handlers/FramesHandler.js +457 -0
- package/models/trace/handlers/FramesHandler.js.map +1 -0
- package/models/trace/handlers/GPUHandler.d.ts +11 -0
- package/models/trace/handlers/GPUHandler.js +54 -0
- package/models/trace/handlers/GPUHandler.js.map +1 -0
- package/models/trace/handlers/InitiatorsHandler.d.ts +10 -0
- package/models/trace/handlers/InitiatorsHandler.js +184 -0
- package/models/trace/handlers/InitiatorsHandler.js.map +1 -0
- package/models/trace/handlers/InvalidationsHandler.d.ts +10 -0
- package/models/trace/handlers/InvalidationsHandler.js +120 -0
- package/models/trace/handlers/InvalidationsHandler.js.map +1 -0
- package/models/trace/handlers/LargestImagePaintHandler.d.ts +5 -0
- package/models/trace/handlers/LargestImagePaintHandler.js +38 -0
- package/models/trace/handlers/LargestImagePaintHandler.js.map +1 -0
- package/models/trace/handlers/LargestTextPaintHandler.d.ts +5 -0
- package/models/trace/handlers/LargestTextPaintHandler.js +26 -0
- package/models/trace/handlers/LargestTextPaintHandler.js.map +1 -0
- package/models/trace/handlers/LayerTreeHandler.d.ts +13 -0
- package/models/trace/handlers/LayerTreeHandler.js +116 -0
- package/models/trace/handlers/LayerTreeHandler.js.map +1 -0
- package/models/trace/handlers/LayoutShiftsHandler.d.ts +44 -0
- package/models/trace/handlers/LayoutShiftsHandler.js +347 -0
- package/models/trace/handlers/LayoutShiftsHandler.js.map +1 -0
- package/models/trace/handlers/MemoryHandler.d.ts +7 -0
- package/models/trace/handlers/MemoryHandler.js +20 -0
- package/models/trace/handlers/MemoryHandler.js.map +1 -0
- package/models/trace/handlers/MetaHandler.d.ts +37 -0
- package/models/trace/handlers/MetaHandler.js +338 -0
- package/models/trace/handlers/MetaHandler.js.map +1 -0
- package/models/trace/handlers/Migration.js +27 -0
- package/models/trace/handlers/Migration.js.map +7 -0
- package/models/trace/handlers/ModelHandlers.d.ts +21 -0
- package/models/trace/handlers/ModelHandlers.js +25 -0
- package/models/trace/handlers/ModelHandlers.js.map +1 -0
- package/models/trace/handlers/NetworkRequestsHandler.d.ts +17 -0
- package/models/trace/handlers/NetworkRequestsHandler.js +361 -0
- package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -0
- package/models/trace/handlers/PageLoadMetricsHandler.d.ts +67 -0
- package/models/trace/handlers/PageLoadMetricsHandler.js +407 -0
- package/models/trace/handlers/PageLoadMetricsHandler.js.map +1 -0
- package/models/trace/handlers/RendererHandler.d.ts +101 -0
- package/models/trace/handlers/RendererHandler.js +325 -0
- package/models/trace/handlers/RendererHandler.js.map +1 -0
- package/models/trace/handlers/SamplesHandler.d.ts +46 -0
- package/models/trace/handlers/SamplesHandler.js +215 -0
- package/models/trace/handlers/SamplesHandler.js.map +1 -0
- package/models/trace/handlers/ScreenshotsHandler.d.ts +7 -0
- package/models/trace/handlers/ScreenshotsHandler.js +79 -0
- package/models/trace/handlers/ScreenshotsHandler.js.map +1 -0
- package/models/trace/handlers/Threads.d.ts +33 -0
- package/models/trace/handlers/Threads.js +95 -0
- package/models/trace/handlers/Threads.js.map +1 -0
- package/models/trace/handlers/UberFramesHandler.js +293 -0
- package/models/trace/handlers/UberFramesHandler.js.map +7 -0
- package/models/trace/handlers/UserInteractionsHandler.d.ts +57 -0
- package/models/trace/handlers/UserInteractionsHandler.js +267 -0
- package/models/trace/handlers/UserInteractionsHandler.js.map +1 -0
- package/models/trace/handlers/UserTimingsHandler.d.ts +28 -0
- package/models/trace/handlers/UserTimingsHandler.js +108 -0
- package/models/trace/handlers/UserTimingsHandler.js.map +1 -0
- package/models/trace/handlers/WarningsHandler.d.ts +14 -0
- package/models/trace/handlers/WarningsHandler.js +125 -0
- package/models/trace/handlers/WarningsHandler.js.map +1 -0
- package/models/trace/handlers/WorkersHandler.d.ts +11 -0
- package/models/trace/handlers/WorkersHandler.js +52 -0
- package/models/trace/handlers/WorkersHandler.js.map +1 -0
- package/models/trace/handlers/bundle-tsconfig.json +1 -0
- package/models/trace/handlers/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
- package/models/trace/handlers/handlers-tsconfig.json +79 -0
- package/models/trace/handlers/handlers.d.ts +3 -0
- package/models/trace/handlers/handlers.js +7 -0
- package/models/trace/handlers/handlers.js.map +1 -0
- package/models/trace/handlers/types.d.ts +45 -0
- package/models/trace/handlers/types.js +18 -0
- package/models/trace/handlers/types.js.map +1 -0
- package/models/trace/helpers/SamplesIntegrator.d.ts +49 -0
- package/models/trace/helpers/SamplesIntegrator.js +397 -0
- package/models/trace/helpers/SamplesIntegrator.js.map +1 -0
- package/models/trace/helpers/Timing.d.ts +26 -0
- package/models/trace/helpers/Timing.js +162 -0
- package/models/trace/helpers/Timing.js.map +1 -0
- package/models/trace/helpers/Trace.d.ts +37 -0
- package/models/trace/helpers/Trace.js +230 -0
- package/models/trace/helpers/Trace.js.map +1 -0
- package/models/trace/helpers/TreeHelpers.d.ts +90 -0
- package/models/trace/helpers/TreeHelpers.js +222 -0
- package/models/trace/helpers/TreeHelpers.js.map +1 -0
- package/models/trace/helpers/bundle-tsconfig.json +1 -0
- package/models/trace/helpers/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
- package/models/trace/helpers/helpers-tsconfig.json +59 -0
- package/models/trace/helpers/helpers.d.ts +4 -0
- package/models/trace/helpers/helpers.js +8 -0
- package/models/trace/helpers/helpers.js.map +1 -0
- package/models/trace/legacy-tsconfig.json +1 -0
- package/models/trace/root-causes/LayoutShift.d.ts +119 -0
- package/models/trace/root-causes/LayoutShift.js +517 -0
- package/models/trace/root-causes/LayoutShift.js.map +1 -0
- package/models/trace/root-causes/RootCauses.d.ts +14 -0
- package/models/trace/root-causes/RootCauses.js +11 -0
- package/models/trace/root-causes/RootCauses.js.map +1 -0
- package/models/trace/root-causes/bundle-tsconfig.json +1 -0
- package/models/trace/root-causes/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
- package/models/trace/root-causes/root-causes-tsconfig.json +57 -0
- package/models/trace/root-causes/root-causes.d.ts +1 -0
- package/models/trace/root-causes/root-causes.js +5 -0
- package/models/trace/root-causes/root-causes.js.map +1 -0
- package/models/trace/sdk_services/DOMNodeLookup.js +41 -0
- package/models/trace/sdk_services/DOMNodeLookup.js.map +7 -0
- package/models/trace/sdk_services/LayoutShifts.js +68 -0
- package/models/trace/sdk_services/LayoutShifts.js.map +7 -0
- package/models/trace/sdk_services/bundle-tsconfig.json +1 -0
- package/models/trace/sdk_services/devtools_entrypoint-bundle-typescript-tsconfig.json +41 -0
- package/models/trace/sdk_services/sdk_services-tsconfig.json +57 -0
- package/models/trace/sdk_services/sdk_services.js +7 -0
- package/models/trace/sdk_services/sdk_services.js.map +7 -0
- package/models/trace/trace-legacy.js +16 -0
- package/models/trace/trace-legacy.js.map +7 -0
- package/models/trace/trace-tsconfig.json +69 -0
- package/models/trace/trace.d.ts +11 -0
- package/models/trace/trace.js +17 -0
- package/models/trace/trace.js.map +1 -0
- package/models/trace/types/Configuration.d.ts +33 -0
- package/models/trace/types/Configuration.js +29 -0
- package/models/trace/types/Configuration.js.map +1 -0
- package/models/trace/types/File.d.ts +23 -0
- package/models/trace/types/File.js +5 -0
- package/models/trace/types/File.js.map +1 -0
- package/models/trace/types/Timing.d.ts +25 -0
- package/models/trace/types/Timing.js +16 -0
- package/models/trace/types/Timing.js.map +1 -0
- package/models/trace/types/TraceEvents.d.ts +1571 -0
- package/models/trace/types/TraceEvents.js +388 -0
- package/models/trace/types/TraceEvents.js.map +1 -0
- package/models/trace/types/bundle-tsconfig.json +1 -0
- package/models/trace/types/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
- package/models/trace/types/types-tsconfig.json +47 -0
- package/models/trace/types/types.d.ts +4 -0
- package/models/trace/types/types.js +8 -0
- package/models/trace/types/types.js.map +1 -0
- package/models/trace/worker/Processor.js +143 -0
- package/models/trace/worker/Processor.js.map +7 -0
- package/models/trace/worker/Types.js +1 -0
- package/models/trace/worker/Types.js.map +7 -0
- package/models/trace/worker/bundle-tsconfig.json +1 -0
- package/models/trace/worker/devtools_entrypoint-bundle-typescript-tsconfig.json +41 -0
- package/models/trace/worker/devtools_entrypoint-worker_entrypoint-typescript-tsconfig.json +41 -0
- package/models/trace/worker/processor-tsconfig.json +45 -0
- package/models/trace/worker/worker.js +7 -0
- package/models/trace/worker/worker.js.map +7 -0
- package/models/trace/worker/worker_entrypoint-tsconfig.json +1 -0
- package/models/trace/worker/worker_entrypoint.js +36 -0
- package/models/trace/worker/worker_entrypoint.js.map +7 -0
- package/package.json +2 -2
- package/TracingManager.js +0 -0
- package/extras/extras.js +0 -0
- package/trace.mjs +0 -6980
- package/trace.mjs.map +0 -8
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../front_end/models/trace/TreeManipulator.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.\nimport * as Platform from '../../core/platform/platform.js';\n\nimport type * as Helpers from './helpers/helpers.js';\nimport type * as Types from './types/types.js';\n\ntype EntryToNodeMap = Map<Types.TraceEvents.TraceEntry, Helpers.TreeHelpers.TraceEntryNode>;\n\nexport const enum TreeAction {\n MERGE_FUNCTION = 'MERGE_FUNCTION',\n COLLAPSE_FUNCTION = 'COLLAPSE_FUNCTION',\n}\n\nexport interface UserTreeAction {\n type: TreeAction;\n entry: Types.TraceEvents.TraceEntry;\n}\n\n/**\n * This class can take in a thread that has been generated by the\n * RendererHandler and apply certain actions to it in order to modify what is\n * shown to the user. These actions can be automatically applied by DevTools or\n * applied by the user.\n *\n * Once actions are applied, the invisibleEntries() method will return the\n * entries that are invisible, and this is the list of entries that should be\n * removed before rendering the resulting thread on the timeline.\n **/\nexport class TreeManipulator {\n // Maps from an individual TraceEvent entry to its representation as a\n // RendererEntryNode. We need this so we can then parse the tree structure\n // generated by the RendererHandler.\n #entryToNode: EntryToNodeMap;\n\n // Track the last calculated set of invisible entries. This means we can avoid\n // re-generating this if the set of actions that have been applied has not\n // changed.\n #lastInvisibleEntries: Types.TraceEvents.TraceEntry[]|null = null;\n #activeActions: UserTreeAction[] = [];\n\n constructor(entryToNode: EntryToNodeMap) {\n this.#entryToNode = entryToNode;\n }\n\n /**\n * Applies an action to the visible tree. This will also clear the cache of\n * invisible entries, ensuring that it will be recalculated with the latest set\n * of actions.\n **/\n applyAction(action: UserTreeAction): void {\n if (this.#actionIsActive(action)) {\n // If the action is already active there is no reason to apply it again.\n return;\n }\n\n this.#activeActions.push(action);\n // Clear the last list of invisible entries - this invalidates the cache and\n // ensures that the invisible list will be recalculated, which we have to do\n // now we have changed the list of actions.\n this.#lastInvisibleEntries = null;\n }\n\n /**\n * Removes a matching action, if one is found, from the active actions set.\n * Note that we do not match on action equality and instead search through\n * the set of active actions for one that is of the same type, and has the\n * same entry associated with it.\n *\n * This is a no-op if the action is not active.\n **/\n removeActiveAction(action: UserTreeAction): void {\n let removedAction = false;\n this.#activeActions = this.#activeActions.filter(activeAction => {\n if (activeAction.type === action.type && activeAction.entry === action.entry) {\n removedAction = true;\n return false;\n }\n return true;\n });\n\n if (removedAction) {\n // If we found and removed an action, we need to clear the cache to force\n // the set of invisible entries to be recalculcated.\n this.#lastInvisibleEntries = null;\n }\n }\n\n #actionIsActive(action: UserTreeAction): boolean {\n return this.#activeActions.some(activeAction => {\n return action.entry === activeAction.entry && action.type === activeAction.type;\n });\n }\n\n /**\n * The set of entries that are invisible given the set of applied actions. If\n * no actions are applied, this will return an empty list of entries.\n *\n * This method is cached, so it is safe to call multiple times.\n **/\n invisibleEntries(): Types.TraceEvents.TraceEventData[] {\n if (this.#activeActions.length === 0) {\n return [];\n }\n return this.#calculateInvisibleEntries();\n }\n\n #calculateInvisibleEntries(): Types.TraceEvents.TraceEventData[] {\n // When an action is added, we clear this cache. So if this cache is\n // present it means that the set of active actions has not changed, and so\n // we do not need to recalculate anything.\n if (this.#lastInvisibleEntries) {\n return this.#lastInvisibleEntries;\n }\n\n // We apply each user action in turn to the set of all entries, and mark\n // any that should be hidden by adding them to this set. We do this to\n // ensure we minimise the amount of passes through the list of all entries.\n // Another approach would be to use splice() to remove items from the\n // array, but doing this would be a mutation of the arry for every hidden\n // event. Instead, we add entries to this set and return it as an array at the end.\n const entriesToHide = new Set<Types.TraceEvents.TraceEntry>();\n\n for (const action of this.#activeActions) {\n switch (action.type) {\n case TreeAction.MERGE_FUNCTION: {\n // The entry that was clicked on is merged into its parent. All its\n // children remain visible, so we just have to hide the entry that was\n // selected.\n entriesToHide.add(action.entry);\n break;\n }\n\n case TreeAction.COLLAPSE_FUNCTION: {\n // The entry itself remains visible, but all of its ancestors are hidden.\n const entryNode = this.#entryToNode.get(action.entry);\n if (!entryNode) {\n // Invalid node was given, just ignore and move on.\n continue;\n }\n const allAncestors = this.#findAllAncestorsOfNode(entryNode);\n allAncestors.forEach(ancestor => entriesToHide.add(ancestor));\n break;\n }\n default:\n Platform.assertNever(action.type, `Unknown TreeManipulator action: ${action.type}`);\n }\n }\n\n // Now we have applied all actions, return the invisible entries.\n // We cache this under lastInvisibleEntries - if this function is called\n // again and the user actions have not changed, we can avoid recalculating\n // this and just return the last one. This cache is automatically cleared\n // when the user actions are changed.\n\n this.#lastInvisibleEntries = [...entriesToHide];\n\n return this.#lastInvisibleEntries;\n }\n\n #findAllAncestorsOfNode(root: Helpers.TreeHelpers.TraceEntryNode): Types.TraceEvents.TraceEntry[] {\n const ancestors: Types.TraceEvents.TraceEntry[] = [];\n\n // Walk through all the ancestors, starting at the root node.\n const children: Helpers.TreeHelpers.TraceEntryNode[] = [...root.children];\n while (children.length > 0) {\n const childNode = children.shift();\n if (childNode) {\n ancestors.push(childNode.entry);\n children.push(...childNode.children);\n }\n }\n\n return ancestors;\n }\n}\n"],
|
|
5
|
+
"mappings": "AAGA;AAOO,WAAW,aAAX,kBAAW,gBAAX;AACL,kCAAiB;AACjB,qCAAoB;AAFJ;AAAA;AAoBX,6BAAsB;AAAA;AAAA,0BASkC;AAAA,mBAC1B;AAAA,EAEnC,YAAY,aAA6B;AACvC,wBAAoB;AAAA;AAAA,EAQtB,YAAY,QAA8B;AACxC,QAAI,qBAAqB,SAAS;AAEhC;AAAA;AAGF,wBAAoB,KAAK;AAIzB,iCAA6B;AAAA;AAAA,EAW/B,mBAAmB,QAA8B;AAC/C,QAAI,gBAAgB;AACpB,0BAAsB,oBAAoB,OAAO,kBAAgB;AAC/D,UAAI,aAAa,SAAS,OAAO,QAAQ,aAAa,UAAU,OAAO,OAAO;AAC5E,wBAAgB;AAChB,eAAO;AAAA;AAET,aAAO;AAAA;AAGT,QAAI,eAAe;AAGjB,mCAA6B;AAAA;AAAA;AAAA,kBAIjB,QAAiC;AAC/C,WAAO,oBAAoB,KAAK,kBAAgB;AAC9C,aAAO,OAAO,UAAU,aAAa,SAAS,OAAO,SAAS,aAAa;AAAA;AAAA;AAAA,EAU/E,mBAAuD;AACrD,QAAI,oBAAoB,WAAW,GAAG;AACpC,aAAO;AAAA;AAET,WAAO;AAAA;AAAA,+BAGwD;AAI/D,QAAI,4BAA4B;AAC9B,aAAO;AAAA;AAST,UAAM,gBAAgB,oBAAI;AAE1B,eAAW,UAAU,qBAAqB;AACxC,cAAQ,OAAO;AAAA,aACR,uCAA2B;AAI9B,wBAAc,IAAI,OAAO;AACzB;AAAA;AAAA,aAGG,6CAA8B;AAEjC,gBAAM,YAAY,kBAAkB,IAAI,OAAO;AAC/C,cAAI,CAAC,WAAW;AAEd;AAAA;AAEF,gBAAM,eAAe,6BAA6B;AAClD,uBAAa,QAAQ,cAAY,cAAc,IAAI;AACnD;AAAA;AAAA;AAGA,mBAAS,YAAY,OAAO,MAAM,mCAAmC,OAAO;AAAA;AAAA;AAUlF,iCAA6B,CAAC,GAAG;AAEjC,WAAO;AAAA;AAAA,0BAGe,MAA0E;AAChG,UAAM,YAA4C;AAGlD,UAAM,WAAiD,CAAC,GAAG,KAAK;AAChE,WAAO,SAAS,SAAS,GAAG;AAC1B,YAAM,YAAY,SAAS;AAC3B,UAAI,WAAW;AACb,kBAAU,KAAK,UAAU;AACzB,iBAAS,KAAK,GAAG,UAAU;AAAA;AAAA;AAI/B,WAAO;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"compilerOptions":{"composite":true,"outDir":".","baseUrl":".","rootDir":"../../../../../../front_end/models/trace"},"files":["../../../../../../front_end/models/trace/trace.ts"],"references":[{"path":"./trace-tsconfig.json"}]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"allowJs": true,
|
|
4
|
+
"checkJs": true,
|
|
5
|
+
"composite": true,
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"experimentalDecorators": true,
|
|
8
|
+
"forceConsistentCasingInFileNames": true,
|
|
9
|
+
"inlineSources": true,
|
|
10
|
+
"lib": [
|
|
11
|
+
"esnext",
|
|
12
|
+
"dom",
|
|
13
|
+
"dom.iterable"
|
|
14
|
+
],
|
|
15
|
+
"module": "esnext",
|
|
16
|
+
"noEmitOnError": true,
|
|
17
|
+
"noFallthroughCasesInSwitch": true,
|
|
18
|
+
"noImplicitOverride": true,
|
|
19
|
+
"noImplicitReturns": true,
|
|
20
|
+
"noUnusedLocals": false,
|
|
21
|
+
"outDir": ".",
|
|
22
|
+
"rootDir": "../../../../../../front_end/models/trace",
|
|
23
|
+
"skipLibCheck": true,
|
|
24
|
+
"sourceMap": true,
|
|
25
|
+
"strict": true,
|
|
26
|
+
"target": "esnext",
|
|
27
|
+
"tsBuildInfoFile": "devtools_entrypoint-bundle-typescript-tsconfig.json.tsbuildinfo",
|
|
28
|
+
"typeRoots": [],
|
|
29
|
+
"useUnknownInCatchVariables": false
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"../../../../../../front_end/models/trace/trace.ts",
|
|
33
|
+
"../../../../../../front_end/legacy/legacy-defs.d.ts",
|
|
34
|
+
"../../../../../../front_end/global_typings/global_defs.d.ts",
|
|
35
|
+
"../../../../../../front_end/global_typings/request_idle_callback.d.ts",
|
|
36
|
+
"../../../../../../node_modules/@types/filesystem/index.d.ts",
|
|
37
|
+
"../../../../../../node_modules/@webgpu/types/dist/index.d.ts"
|
|
38
|
+
],
|
|
39
|
+
"references": [
|
|
40
|
+
{
|
|
41
|
+
"path": "./trace-tsconfig.json"
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"allowJs": true,
|
|
4
|
+
"checkJs": true,
|
|
5
|
+
"composite": true,
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"experimentalDecorators": true,
|
|
8
|
+
"forceConsistentCasingInFileNames": true,
|
|
9
|
+
"inlineSources": true,
|
|
10
|
+
"lib": [
|
|
11
|
+
"esnext",
|
|
12
|
+
"dom",
|
|
13
|
+
"dom.iterable"
|
|
14
|
+
],
|
|
15
|
+
"module": "esnext",
|
|
16
|
+
"noEmitOnError": true,
|
|
17
|
+
"noFallthroughCasesInSwitch": true,
|
|
18
|
+
"noImplicitOverride": true,
|
|
19
|
+
"noImplicitReturns": true,
|
|
20
|
+
"noUnusedLocals": false,
|
|
21
|
+
"outDir": ".",
|
|
22
|
+
"rootDir": "../../../../../../front_end/models/trace",
|
|
23
|
+
"skipLibCheck": true,
|
|
24
|
+
"sourceMap": true,
|
|
25
|
+
"strict": true,
|
|
26
|
+
"target": "esnext",
|
|
27
|
+
"tsBuildInfoFile": "devtools_entrypoint-legacy-typescript-tsconfig.json.tsbuildinfo",
|
|
28
|
+
"typeRoots": [],
|
|
29
|
+
"useUnknownInCatchVariables": false
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"../../../../../../front_end/models/trace/trace-legacy.ts",
|
|
33
|
+
"../../../../../../front_end/legacy/legacy-defs.d.ts",
|
|
34
|
+
"../../../../../../front_end/global_typings/global_defs.d.ts",
|
|
35
|
+
"../../../../../../front_end/global_typings/request_idle_callback.d.ts",
|
|
36
|
+
"../../../../../../node_modules/@types/filesystem/index.d.ts"
|
|
37
|
+
],
|
|
38
|
+
"references": [
|
|
39
|
+
{
|
|
40
|
+
"path": "./bundle-tsconfig.json"
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type * as Protocol from '../../../generated/protocol.js';
|
|
2
|
+
import * as SDK from '../../../core/sdk/sdk.js';
|
|
3
|
+
import type * as Handlers from '../handlers/handlers.js';
|
|
4
|
+
import type * as Types from '../types/types.js';
|
|
5
|
+
export declare function _TEST_clearCache(): void;
|
|
6
|
+
/**
|
|
7
|
+
* Looks up the DOM Node on the page for the given BackendNodeId. Uses the
|
|
8
|
+
* provided TraceParseData as the cache and will cache the result after the
|
|
9
|
+
* first lookup.
|
|
10
|
+
*/
|
|
11
|
+
export declare function domNodeForBackendNodeID(modelData: Handlers.Types.TraceParseData, nodeId: Protocol.DOM.BackendNodeId): Promise<SDK.DOMModel.DOMNode | null>;
|
|
12
|
+
/**
|
|
13
|
+
* Takes a set of Protocol.DOM.BackendNodeId ids and will return a map of NodeId=>DOMNode.
|
|
14
|
+
* Results are cached based on 1) the provided TraceParseData and 2) the provided set of IDs.
|
|
15
|
+
*/
|
|
16
|
+
export declare function domNodesForMultipleBackendNodeIds(modelData: Handlers.Types.TraceParseData, nodeIds: Set<Protocol.DOM.BackendNodeId>): Promise<Map<Protocol.DOM.BackendNodeId, SDK.DOMModel.DOMNode | null>>;
|
|
17
|
+
export interface LayoutShiftSource {
|
|
18
|
+
previousRect: DOMRect;
|
|
19
|
+
currentRect: DOMRect;
|
|
20
|
+
node: SDK.DOMModel.DOMNode;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Calculates and returns a list of sources for a LayoutShift.
|
|
24
|
+
* Here, a source is considered as a node that moved and contributed to the
|
|
25
|
+
* given LayoutShift existing and the score it was given. Each source returned
|
|
26
|
+
* contains a reference to the DOM Node, and its dimensions (as a DOMRect), both
|
|
27
|
+
* before and now, so we can see how this node changed and how that impacted the
|
|
28
|
+
* layout shift.
|
|
29
|
+
*
|
|
30
|
+
* This data is cached based on the provided model data and the given layout
|
|
31
|
+
* shift, so it is is safe to call multiple times with the same input.
|
|
32
|
+
*/
|
|
33
|
+
export declare function sourcesForLayoutShift(modelData: Handlers.Types.TraceParseData, event: Types.TraceEvents.TraceEventLayoutShift): Promise<readonly LayoutShiftSource[]>;
|
|
34
|
+
/**
|
|
35
|
+
* Takes a LayoutShift and normalizes its node dimensions based on the device
|
|
36
|
+
* pixel ratio (DPR) of the user's display.
|
|
37
|
+
* This is required because the Layout Instability API is not based on CSS
|
|
38
|
+
* pixels, but physical pixels. Therefore we need to map these to normalized CSS
|
|
39
|
+
* pixels if we can. For example, if the user is on a device with a DPR of 2,
|
|
40
|
+
* the values of the node dimensions reported by the Instability API need to be
|
|
41
|
+
* divided by 2 to be accurate.
|
|
42
|
+
* This function is safe to call multiple times as results are cached based on
|
|
43
|
+
* the provided model data.
|
|
44
|
+
* See https://crbug.com/1300309 for details.
|
|
45
|
+
*/
|
|
46
|
+
export declare function normalizedImpactedNodesForLayoutShift(modelData: Handlers.Types.TraceParseData, event: Types.TraceEvents.TraceEventLayoutShift): Promise<readonly Types.TraceEvents.TraceImpactedNode[]>;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// Copyright 2023 The Chromium Authors. All rights reserved.
|
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
import * as SDK from '../../../core/sdk/sdk.js';
|
|
5
|
+
const domLookUpSingleNodeCache = new Map();
|
|
6
|
+
const domLookUpBatchNodesCache = new Map();
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
8
|
+
export function _TEST_clearCache() {
|
|
9
|
+
domLookUpSingleNodeCache.clear();
|
|
10
|
+
domLookUpBatchNodesCache.clear();
|
|
11
|
+
layoutShiftSourcesCache.clear();
|
|
12
|
+
normalizedLayoutShiftNodesCache.clear();
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Looks up the DOM Node on the page for the given BackendNodeId. Uses the
|
|
16
|
+
* provided TraceParseData as the cache and will cache the result after the
|
|
17
|
+
* first lookup.
|
|
18
|
+
*/
|
|
19
|
+
export async function domNodeForBackendNodeID(modelData, nodeId) {
|
|
20
|
+
const fromCache = domLookUpSingleNodeCache.get(modelData)?.get(nodeId);
|
|
21
|
+
if (fromCache !== undefined) {
|
|
22
|
+
return fromCache;
|
|
23
|
+
}
|
|
24
|
+
const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
|
|
25
|
+
const domModel = target?.model(SDK.DOMModel.DOMModel);
|
|
26
|
+
if (!domModel) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const domNodesMap = await domModel.pushNodesByBackendIdsToFrontend(new Set([nodeId]));
|
|
30
|
+
const result = domNodesMap?.get(nodeId) || null;
|
|
31
|
+
const cacheForModel = domLookUpSingleNodeCache.get(modelData) || new Map();
|
|
32
|
+
cacheForModel.set(nodeId, result);
|
|
33
|
+
domLookUpSingleNodeCache.set(modelData, cacheForModel);
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Takes a set of Protocol.DOM.BackendNodeId ids and will return a map of NodeId=>DOMNode.
|
|
38
|
+
* Results are cached based on 1) the provided TraceParseData and 2) the provided set of IDs.
|
|
39
|
+
*/
|
|
40
|
+
export async function domNodesForMultipleBackendNodeIds(modelData, nodeIds) {
|
|
41
|
+
const fromCache = domLookUpBatchNodesCache.get(modelData)?.get(nodeIds);
|
|
42
|
+
if (fromCache) {
|
|
43
|
+
return fromCache;
|
|
44
|
+
}
|
|
45
|
+
const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
|
|
46
|
+
const domModel = target?.model(SDK.DOMModel.DOMModel);
|
|
47
|
+
if (!domModel) {
|
|
48
|
+
return new Map();
|
|
49
|
+
}
|
|
50
|
+
const domNodesMap = await domModel.pushNodesByBackendIdsToFrontend(nodeIds) || new Map();
|
|
51
|
+
const cacheForModel = domLookUpBatchNodesCache.get(modelData) ||
|
|
52
|
+
new Map();
|
|
53
|
+
cacheForModel.set(nodeIds, domNodesMap);
|
|
54
|
+
domLookUpBatchNodesCache.set(modelData, cacheForModel);
|
|
55
|
+
return domNodesMap;
|
|
56
|
+
}
|
|
57
|
+
const layoutShiftSourcesCache = new Map();
|
|
58
|
+
const normalizedLayoutShiftNodesCache = new Map();
|
|
59
|
+
/**
|
|
60
|
+
* Calculates and returns a list of sources for a LayoutShift.
|
|
61
|
+
* Here, a source is considered as a node that moved and contributed to the
|
|
62
|
+
* given LayoutShift existing and the score it was given. Each source returned
|
|
63
|
+
* contains a reference to the DOM Node, and its dimensions (as a DOMRect), both
|
|
64
|
+
* before and now, so we can see how this node changed and how that impacted the
|
|
65
|
+
* layout shift.
|
|
66
|
+
*
|
|
67
|
+
* This data is cached based on the provided model data and the given layout
|
|
68
|
+
* shift, so it is is safe to call multiple times with the same input.
|
|
69
|
+
*/
|
|
70
|
+
export async function sourcesForLayoutShift(modelData, event) {
|
|
71
|
+
const fromCache = layoutShiftSourcesCache.get(modelData)?.get(event);
|
|
72
|
+
if (fromCache) {
|
|
73
|
+
return fromCache;
|
|
74
|
+
}
|
|
75
|
+
const impactedNodes = event.args.data?.impacted_nodes;
|
|
76
|
+
if (!impactedNodes) {
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
const sources = [];
|
|
80
|
+
await Promise.all(impactedNodes.map(async (node) => {
|
|
81
|
+
const domNode = await domNodeForBackendNodeID(modelData, node.node_id);
|
|
82
|
+
if (domNode) {
|
|
83
|
+
sources.push({
|
|
84
|
+
previousRect: new DOMRect(node.old_rect[0], node.old_rect[1], node.old_rect[2], node.old_rect[3]),
|
|
85
|
+
currentRect: new DOMRect(node.new_rect[0], node.new_rect[1], node.new_rect[2], node.new_rect[3]),
|
|
86
|
+
node: domNode,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}));
|
|
90
|
+
const cacheForModel = layoutShiftSourcesCache.get(modelData) || new Map();
|
|
91
|
+
cacheForModel.set(event, sources);
|
|
92
|
+
layoutShiftSourcesCache.set(modelData, cacheForModel);
|
|
93
|
+
return sources;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Takes a LayoutShift and normalizes its node dimensions based on the device
|
|
97
|
+
* pixel ratio (DPR) of the user's display.
|
|
98
|
+
* This is required because the Layout Instability API is not based on CSS
|
|
99
|
+
* pixels, but physical pixels. Therefore we need to map these to normalized CSS
|
|
100
|
+
* pixels if we can. For example, if the user is on a device with a DPR of 2,
|
|
101
|
+
* the values of the node dimensions reported by the Instability API need to be
|
|
102
|
+
* divided by 2 to be accurate.
|
|
103
|
+
* This function is safe to call multiple times as results are cached based on
|
|
104
|
+
* the provided model data.
|
|
105
|
+
* See https://crbug.com/1300309 for details.
|
|
106
|
+
*/
|
|
107
|
+
export async function normalizedImpactedNodesForLayoutShift(modelData, event) {
|
|
108
|
+
const fromCache = normalizedLayoutShiftNodesCache.get(modelData)?.get(event);
|
|
109
|
+
if (fromCache) {
|
|
110
|
+
return fromCache;
|
|
111
|
+
}
|
|
112
|
+
const impactedNodes = event.args?.data?.impacted_nodes;
|
|
113
|
+
if (!impactedNodes) {
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
116
|
+
let viewportScale = null;
|
|
117
|
+
const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
|
|
118
|
+
// Get the CSS-to-physical pixel ratio of the device the inspected
|
|
119
|
+
// target is running at.
|
|
120
|
+
const evaluateResult = await target?.runtimeAgent().invoke_evaluate({ expression: 'window.devicePixelRatio' });
|
|
121
|
+
if (evaluateResult?.result.type === 'number') {
|
|
122
|
+
viewportScale = evaluateResult?.result.value ?? null;
|
|
123
|
+
}
|
|
124
|
+
if (!viewportScale) {
|
|
125
|
+
// Bail and return the nodes as is.
|
|
126
|
+
return impactedNodes;
|
|
127
|
+
}
|
|
128
|
+
const normalizedNodes = [];
|
|
129
|
+
for (const impactedNode of impactedNodes) {
|
|
130
|
+
const newNode = { ...impactedNode };
|
|
131
|
+
for (let i = 0; i < impactedNode.old_rect.length; i++) {
|
|
132
|
+
newNode.old_rect[i] /= viewportScale;
|
|
133
|
+
}
|
|
134
|
+
for (let i = 0; i < impactedNode.new_rect.length; i++) {
|
|
135
|
+
newNode.new_rect[i] /= viewportScale;
|
|
136
|
+
}
|
|
137
|
+
normalizedNodes.push(newNode);
|
|
138
|
+
}
|
|
139
|
+
const cacheForModel = normalizedLayoutShiftNodesCache.get(modelData) ||
|
|
140
|
+
new Map();
|
|
141
|
+
cacheForModel.set(event, normalizedNodes);
|
|
142
|
+
normalizedLayoutShiftNodesCache.set(modelData, cacheForModel);
|
|
143
|
+
return normalizedNodes;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=FetchNodes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FetchNodes.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/extras/FetchNodes.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport type * as Protocol from '../../../generated/protocol.js';\nimport * as SDK from '../../../core/sdk/sdk.js';\nimport type * as Handlers from '../handlers/handlers.js';\nimport type * as Types from '../types/types.js';\n\nconst domLookUpSingleNodeCache =\n new Map<Handlers.Types.TraceParseData, Map<Protocol.DOM.BackendNodeId, SDK.DOMModel.DOMNode|null>>();\nconst domLookUpBatchNodesCache = new Map<\n Handlers.Types.TraceParseData,\n Map<Set<Protocol.DOM.BackendNodeId>, Map<Protocol.DOM.BackendNodeId, SDK.DOMModel.DOMNode|null>>>();\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function _TEST_clearCache(): void {\n domLookUpSingleNodeCache.clear();\n domLookUpBatchNodesCache.clear();\n layoutShiftSourcesCache.clear();\n normalizedLayoutShiftNodesCache.clear();\n}\n\n/**\n * Looks up the DOM Node on the page for the given BackendNodeId. Uses the\n * provided TraceParseData as the cache and will cache the result after the\n * first lookup.\n */\nexport async function domNodeForBackendNodeID(\n modelData: Handlers.Types.TraceParseData, nodeId: Protocol.DOM.BackendNodeId): Promise<SDK.DOMModel.DOMNode|null> {\n const fromCache = domLookUpSingleNodeCache.get(modelData)?.get(nodeId);\n if (fromCache !== undefined) {\n return fromCache;\n }\n\n const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();\n const domModel = target?.model(SDK.DOMModel.DOMModel);\n if (!domModel) {\n return null;\n }\n\n const domNodesMap = await domModel.pushNodesByBackendIdsToFrontend(new Set([nodeId]));\n const result = domNodesMap?.get(nodeId) || null;\n\n const cacheForModel =\n domLookUpSingleNodeCache.get(modelData) || new Map<Protocol.DOM.BackendNodeId, SDK.DOMModel.DOMNode|null>();\n cacheForModel.set(nodeId, result);\n domLookUpSingleNodeCache.set(modelData, cacheForModel);\n\n return result;\n}\n\n/**\n * Takes a set of Protocol.DOM.BackendNodeId ids and will return a map of NodeId=>DOMNode.\n * Results are cached based on 1) the provided TraceParseData and 2) the provided set of IDs.\n */\nexport async function domNodesForMultipleBackendNodeIds(\n modelData: Handlers.Types.TraceParseData,\n nodeIds: Set<Protocol.DOM.BackendNodeId>): Promise<Map<Protocol.DOM.BackendNodeId, SDK.DOMModel.DOMNode|null>> {\n const fromCache = domLookUpBatchNodesCache.get(modelData)?.get(nodeIds);\n if (fromCache) {\n return fromCache;\n }\n const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();\n const domModel = target?.model(SDK.DOMModel.DOMModel);\n if (!domModel) {\n return new Map();\n }\n\n const domNodesMap = await domModel.pushNodesByBackendIdsToFrontend(nodeIds) || new Map();\n\n const cacheForModel = domLookUpBatchNodesCache.get(modelData) ||\n new Map<Set<Protocol.DOM.BackendNodeId>, Map<Protocol.DOM.BackendNodeId, SDK.DOMModel.DOMNode|null>>();\n cacheForModel.set(nodeIds, domNodesMap);\n domLookUpBatchNodesCache.set(modelData, cacheForModel);\n\n return domNodesMap;\n}\n\nconst layoutShiftSourcesCache = new Map<\n Handlers.Types.TraceParseData, Map<Types.TraceEvents.TraceEventLayoutShift, readonly LayoutShiftSource[]>>();\n\nconst normalizedLayoutShiftNodesCache = new Map<\n Handlers.Types.TraceParseData,\n Map<Types.TraceEvents.TraceEventLayoutShift, readonly Types.TraceEvents.TraceImpactedNode[]>>();\n\nexport interface LayoutShiftSource {\n previousRect: DOMRect;\n currentRect: DOMRect;\n node: SDK.DOMModel.DOMNode;\n}\n\n/**\n * Calculates and returns a list of sources for a LayoutShift.\n * Here, a source is considered as a node that moved and contributed to the\n * given LayoutShift existing and the score it was given. Each source returned\n * contains a reference to the DOM Node, and its dimensions (as a DOMRect), both\n * before and now, so we can see how this node changed and how that impacted the\n * layout shift.\n *\n * This data is cached based on the provided model data and the given layout\n * shift, so it is is safe to call multiple times with the same input.\n */\nexport async function sourcesForLayoutShift(\n modelData: Handlers.Types.TraceParseData,\n event: Types.TraceEvents.TraceEventLayoutShift): Promise<readonly LayoutShiftSource[]> {\n const fromCache = layoutShiftSourcesCache.get(modelData)?.get(event);\n if (fromCache) {\n return fromCache;\n }\n const impactedNodes = event.args.data?.impacted_nodes;\n if (!impactedNodes) {\n return [];\n }\n const sources: LayoutShiftSource[] = [];\n await Promise.all(impactedNodes.map(async node => {\n const domNode = await domNodeForBackendNodeID(modelData, node.node_id);\n if (domNode) {\n sources.push({\n previousRect: new DOMRect(node.old_rect[0], node.old_rect[1], node.old_rect[2], node.old_rect[3]),\n currentRect: new DOMRect(node.new_rect[0], node.new_rect[1], node.new_rect[2], node.new_rect[3]),\n node: domNode,\n });\n }\n }));\n const cacheForModel =\n layoutShiftSourcesCache.get(modelData) || new Map<Types.TraceEvents.TraceEventLayoutShift, LayoutShiftSource[]>();\n cacheForModel.set(event, sources);\n layoutShiftSourcesCache.set(modelData, cacheForModel);\n return sources;\n}\n\n/**\n * Takes a LayoutShift and normalizes its node dimensions based on the device\n * pixel ratio (DPR) of the user's display.\n * This is required because the Layout Instability API is not based on CSS\n * pixels, but physical pixels. Therefore we need to map these to normalized CSS\n * pixels if we can. For example, if the user is on a device with a DPR of 2,\n * the values of the node dimensions reported by the Instability API need to be\n * divided by 2 to be accurate.\n * This function is safe to call multiple times as results are cached based on\n * the provided model data.\n * See https://crbug.com/1300309 for details.\n */\nexport async function normalizedImpactedNodesForLayoutShift(\n modelData: Handlers.Types.TraceParseData,\n event: Types.TraceEvents.TraceEventLayoutShift): Promise<readonly Types.TraceEvents.TraceImpactedNode[]> {\n const fromCache = normalizedLayoutShiftNodesCache.get(modelData)?.get(event);\n if (fromCache) {\n return fromCache;\n }\n const impactedNodes = event.args?.data?.impacted_nodes;\n if (!impactedNodes) {\n return [];\n }\n\n let viewportScale: number|null = null;\n const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();\n // Get the CSS-to-physical pixel ratio of the device the inspected\n // target is running at.\n const evaluateResult = await target?.runtimeAgent().invoke_evaluate({expression: 'window.devicePixelRatio'});\n if (evaluateResult?.result.type === 'number') {\n viewportScale = evaluateResult?.result.value as number ?? null;\n }\n\n if (!viewportScale) {\n // Bail and return the nodes as is.\n return impactedNodes;\n }\n\n const normalizedNodes: Types.TraceEvents.TraceImpactedNode[] = [];\n for (const impactedNode of impactedNodes) {\n const newNode = {...impactedNode};\n for (let i = 0; i < impactedNode.old_rect.length; i++) {\n newNode.old_rect[i] /= viewportScale;\n }\n for (let i = 0; i < impactedNode.new_rect.length; i++) {\n newNode.new_rect[i] /= viewportScale;\n }\n normalizedNodes.push(newNode);\n }\n\n const cacheForModel = normalizedLayoutShiftNodesCache.get(modelData) ||\n new Map<Types.TraceEvents.TraceEventLayoutShift, readonly Types.TraceEvents.TraceImpactedNode[]>();\n cacheForModel.set(event, normalizedNodes);\n normalizedLayoutShiftNodesCache.set(modelData, cacheForModel);\n\n return normalizedNodes;\n}\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type * as Handlers from '../handlers/handlers.js';
|
|
2
|
+
import type * as Types from '../types/types.js';
|
|
3
|
+
export interface Data {
|
|
4
|
+
zeroTime: Types.Timing.MicroSeconds;
|
|
5
|
+
spanTime: Types.Timing.MicroSeconds;
|
|
6
|
+
frames: readonly Frame[];
|
|
7
|
+
}
|
|
8
|
+
export interface Frame {
|
|
9
|
+
screenshotEvent: Types.TraceEvents.SyntheticScreenshot;
|
|
10
|
+
index: number;
|
|
11
|
+
}
|
|
12
|
+
export type HandlersWithFilmStrip = Handlers.Types.HandlersWithMeta<{
|
|
13
|
+
Screenshots: typeof Handlers.ModelHandlers.Screenshots;
|
|
14
|
+
}>;
|
|
15
|
+
export type HandlerDataWithScreenshots = Handlers.Types.EnabledHandlerDataWithMeta<{
|
|
16
|
+
Screenshots: typeof Handlers.ModelHandlers.Screenshots;
|
|
17
|
+
}>;
|
|
18
|
+
export declare function fromTraceData(traceData: HandlerDataWithScreenshots, customZeroTime?: Types.Timing.MicroSeconds): Data;
|
|
19
|
+
export declare function frameClosestToTimestamp(filmStrip: Data, searchTimestamp: Types.Timing.MicroSeconds): Frame | null;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Copyright 2023 The Chromium Authors. All rights reserved.
|
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
//
|
|
5
|
+
import * as Platform from '../../../core/platform/platform.js';
|
|
6
|
+
// Cache film strips based on:
|
|
7
|
+
// 1. The trace parsed data object
|
|
8
|
+
// 2. The start time.
|
|
9
|
+
const filmStripCache = new Map();
|
|
10
|
+
export function fromTraceData(traceData, customZeroTime) {
|
|
11
|
+
const frames = [];
|
|
12
|
+
const zeroTime = typeof customZeroTime !== 'undefined' ? customZeroTime : traceData.Meta.traceBounds.min;
|
|
13
|
+
const spanTime = traceData.Meta.traceBounds.range;
|
|
14
|
+
const fromCache = filmStripCache.get(traceData)?.get(zeroTime);
|
|
15
|
+
if (fromCache) {
|
|
16
|
+
return fromCache;
|
|
17
|
+
}
|
|
18
|
+
for (const screenshotEvent of traceData.Screenshots) {
|
|
19
|
+
if (screenshotEvent.ts < zeroTime) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
const frame = {
|
|
23
|
+
index: frames.length,
|
|
24
|
+
screenshotEvent: screenshotEvent,
|
|
25
|
+
};
|
|
26
|
+
frames.push(frame);
|
|
27
|
+
}
|
|
28
|
+
const result = {
|
|
29
|
+
zeroTime,
|
|
30
|
+
spanTime,
|
|
31
|
+
frames: Array.from(frames),
|
|
32
|
+
};
|
|
33
|
+
const cachedForData = Platform.MapUtilities.getWithDefault(filmStripCache, traceData, () => new Map());
|
|
34
|
+
cachedForData.set(zeroTime, result);
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
export function frameClosestToTimestamp(filmStrip, searchTimestamp) {
|
|
38
|
+
const closestFrameIndexBeforeTimestamp = Platform.ArrayUtilities.nearestIndexFromEnd(filmStrip.frames, frame => frame.screenshotEvent.ts < searchTimestamp);
|
|
39
|
+
if (closestFrameIndexBeforeTimestamp === null) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
return filmStrip.frames[closestFrameIndexBeforeTimestamp];
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=FilmStrip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilmStrip.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/extras/FilmStrip.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAC7B,EAAE;AACF,OAAO,KAAK,QAAQ,MAAM,oCAAoC,CAAC;AAyB/D,8BAA8B;AAC9B,kCAAkC;AAClC,qBAAqB;AACrB,MAAM,cAAc,GAAG,IAAI,GAAG,EAAoE,CAAC;AAEnG,MAAM,UAAU,aAAa,CAAC,SAAqC,EAAE,cAA0C;IAC7G,MAAM,MAAM,GAAY,EAAE,CAAC;IAE3B,MAAM,QAAQ,GAAG,OAAO,cAAc,KAAK,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC;IACzG,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;IAClD,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC/D,IAAI,SAAS,EAAE;QACb,OAAO,SAAS,CAAC;KAClB;IAED,KAAK,MAAM,eAAe,IAAI,SAAS,CAAC,WAAW,EAAE;QACnD,IAAI,eAAe,CAAC,EAAE,GAAG,QAAQ,EAAE;YACjC,SAAS;SACV;QACD,MAAM,KAAK,GAAU;YACnB,KAAK,EAAE,MAAM,CAAC,MAAM;YACpB,eAAe,EAAE,eAAe;SACjC,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;KACpB;IAED,MAAM,MAAM,GAAS;QACnB,QAAQ;QACR,QAAQ;QACR,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;KAC3B,CAAC;IAEF,MAAM,aAAa,GACf,QAAQ,CAAC,YAAY,CAAC,cAAc,CAAC,cAAc,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,GAAG,EAAmC,CAAC,CAAC;IACtH,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAEpC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,SAAe,EAAE,eAA0C;IACjG,MAAM,gCAAgC,GAAG,QAAQ,CAAC,cAAc,CAAC,mBAAmB,CAChF,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,GAAG,eAAe,CAAC,CAAC;IAC3E,IAAI,gCAAgC,KAAK,IAAI,EAAE;QAC7C,OAAO,IAAI,CAAC;KACb;IACD,OAAO,SAAS,CAAC,MAAM,CAAC,gCAAgC,CAAC,CAAC;AAC5D,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 Platform from '../../../core/platform/platform.js';\nimport type * as Handlers from '../handlers/handlers.js';\nimport type * as Types from '../types/types.js';\n\nexport interface Data {\n zeroTime: Types.Timing.MicroSeconds;\n spanTime: Types.Timing.MicroSeconds;\n frames: readonly Frame[];\n}\n\nexport interface Frame {\n screenshotEvent: Types.TraceEvents.SyntheticScreenshot;\n index: number;\n}\n\nexport type HandlersWithFilmStrip = Handlers.Types.HandlersWithMeta<{\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Screenshots: typeof Handlers.ModelHandlers.Screenshots,\n}>;\n\nexport type HandlerDataWithScreenshots = Handlers.Types.EnabledHandlerDataWithMeta<{\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Screenshots: typeof Handlers.ModelHandlers.Screenshots,\n}>;\n\n// Cache film strips based on:\n// 1. The trace parsed data object\n// 2. The start time.\nconst filmStripCache = new Map<HandlerDataWithScreenshots, Map<Types.Timing.MicroSeconds, Data>>();\n\nexport function fromTraceData(traceData: HandlerDataWithScreenshots, customZeroTime?: Types.Timing.MicroSeconds): Data {\n const frames: Frame[] = [];\n\n const zeroTime = typeof customZeroTime !== 'undefined' ? customZeroTime : traceData.Meta.traceBounds.min;\n const spanTime = traceData.Meta.traceBounds.range;\n const fromCache = filmStripCache.get(traceData)?.get(zeroTime);\n if (fromCache) {\n return fromCache;\n }\n\n for (const screenshotEvent of traceData.Screenshots) {\n if (screenshotEvent.ts < zeroTime) {\n continue;\n }\n const frame: Frame = {\n index: frames.length,\n screenshotEvent: screenshotEvent,\n };\n frames.push(frame);\n }\n\n const result: Data = {\n zeroTime,\n spanTime,\n frames: Array.from(frames),\n };\n\n const cachedForData =\n Platform.MapUtilities.getWithDefault(filmStripCache, traceData, () => new Map<Types.Timing.MicroSeconds, Data>());\n cachedForData.set(zeroTime, result);\n\n return result;\n}\n\nexport function frameClosestToTimestamp(filmStrip: Data, searchTimestamp: Types.Timing.MicroSeconds): Frame|null {\n const closestFrameIndexBeforeTimestamp = Platform.ArrayUtilities.nearestIndexFromEnd(\n filmStrip.frames, frame => frame.screenshotEvent.ts < searchTimestamp);\n if (closestFrameIndexBeforeTimestamp === null) {\n return null;\n }\n return filmStrip.frames[closestFrameIndexBeforeTimestamp];\n}\n"]}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Copyright 2023 The Chromium Authors. All rights reserved.
|
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
import * as Helpers from '../helpers/helpers.js';
|
|
5
|
+
import * as Types from '../types/types.js';
|
|
6
|
+
const IDLE_FUNCTION_CALL_NAMES = new Set([
|
|
7
|
+
'(program)',
|
|
8
|
+
'(idle)',
|
|
9
|
+
'(root)',
|
|
10
|
+
]);
|
|
11
|
+
export function calculateWindow(traceBounds, mainThreadEntries) {
|
|
12
|
+
if (!mainThreadEntries.length) {
|
|
13
|
+
return traceBounds;
|
|
14
|
+
}
|
|
15
|
+
const entriesWithIdleRemoved = mainThreadEntries.filter(entry => {
|
|
16
|
+
if (Types.TraceEvents.isProfileCall(entry) &&
|
|
17
|
+
(IDLE_FUNCTION_CALL_NAMES.has(entry.callFrame.functionName) || !entry.callFrame.functionName)) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
return true;
|
|
21
|
+
});
|
|
22
|
+
if (entriesWithIdleRemoved.length === 0) {
|
|
23
|
+
return traceBounds;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Calculates regions of low utilization and returns the index of the event
|
|
27
|
+
* that is the first event that should be included.
|
|
28
|
+
**/
|
|
29
|
+
function findLowUtilizationRegion(startIndex, stopIndex) {
|
|
30
|
+
const threshold = 0.1;
|
|
31
|
+
let cutIndex = startIndex;
|
|
32
|
+
const entryAtCut = entriesWithIdleRemoved[cutIndex];
|
|
33
|
+
const timings = Helpers.Timing.eventTimingsMicroSeconds(entryAtCut);
|
|
34
|
+
let cutTime = (timings.startTime + timings.endTime) / 2;
|
|
35
|
+
let usedTime = 0;
|
|
36
|
+
const step = Math.sign(stopIndex - startIndex);
|
|
37
|
+
for (let i = startIndex; i !== stopIndex; i += step) {
|
|
38
|
+
const task = entriesWithIdleRemoved[i];
|
|
39
|
+
const taskTimings = Helpers.Timing.eventTimingsMicroSeconds(task);
|
|
40
|
+
const taskTime = (taskTimings.startTime + taskTimings.endTime) / 2;
|
|
41
|
+
const interval = Math.abs(cutTime - taskTime);
|
|
42
|
+
if (usedTime < threshold * interval) {
|
|
43
|
+
cutIndex = i;
|
|
44
|
+
cutTime = taskTime;
|
|
45
|
+
usedTime = 0;
|
|
46
|
+
}
|
|
47
|
+
usedTime += taskTimings.duration;
|
|
48
|
+
}
|
|
49
|
+
return cutIndex;
|
|
50
|
+
}
|
|
51
|
+
const rightIndex = findLowUtilizationRegion(entriesWithIdleRemoved.length - 1, 0);
|
|
52
|
+
const leftIndex = findLowUtilizationRegion(0, rightIndex);
|
|
53
|
+
const leftTimings = Helpers.Timing.eventTimingsMicroSeconds(entriesWithIdleRemoved[leftIndex]);
|
|
54
|
+
const rightTimings = Helpers.Timing.eventTimingsMicroSeconds(entriesWithIdleRemoved[rightIndex]);
|
|
55
|
+
let leftTime = leftTimings.startTime;
|
|
56
|
+
let rightTime = rightTimings.endTime;
|
|
57
|
+
const zoomedInSpan = rightTime - leftTime;
|
|
58
|
+
if (zoomedInSpan < traceBounds.range * 0.1) {
|
|
59
|
+
// If the area we have chosen to zoom into is less than 10% of the entire
|
|
60
|
+
// span, we bail and show the entire trace. It would not be so useful to
|
|
61
|
+
// the user to zoom in on such a small area; we assume they have
|
|
62
|
+
// purposefully recorded a trace that contains empty periods of time.
|
|
63
|
+
return traceBounds;
|
|
64
|
+
}
|
|
65
|
+
// Adjust the left time down by 5%, and the right time up by 5%, so that
|
|
66
|
+
// we give the range we want to zoom a bit of breathing space. At the
|
|
67
|
+
// same time, ensure that we do not stray beyond the bounds of the
|
|
68
|
+
// min/max time of the entire trace.
|
|
69
|
+
leftTime = Types.Timing.MicroSeconds(Math.max(leftTime - 0.05 * zoomedInSpan, traceBounds.min));
|
|
70
|
+
rightTime = Types.Timing.MicroSeconds(Math.min(rightTime + 0.05 * zoomedInSpan, traceBounds.max));
|
|
71
|
+
return {
|
|
72
|
+
min: leftTime,
|
|
73
|
+
max: rightTime,
|
|
74
|
+
range: Types.Timing.MicroSeconds(rightTime - leftTime),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=MainThreadActivity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MainThreadActivity.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/extras/MainThreadActivity.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.\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nconst IDLE_FUNCTION_CALL_NAMES = new Set([\n '(program)',\n '(idle)',\n '(root)',\n]);\n\nexport function calculateWindow(\n traceBounds: Types.Timing.TraceWindowMicroSeconds,\n mainThreadEntries: readonly Types.TraceEvents.SyntheticTraceEntry[]): Types.Timing.TraceWindowMicroSeconds {\n if (!mainThreadEntries.length) {\n return traceBounds;\n }\n const entriesWithIdleRemoved = mainThreadEntries.filter(entry => {\n if (Types.TraceEvents.isProfileCall(entry) &&\n (IDLE_FUNCTION_CALL_NAMES.has(entry.callFrame.functionName) || !entry.callFrame.functionName)) {\n return false;\n }\n return true;\n });\n\n if (entriesWithIdleRemoved.length === 0) {\n return traceBounds;\n }\n /**\n * Calculates regions of low utilization and returns the index of the event\n * that is the first event that should be included.\n **/\n function findLowUtilizationRegion(startIndex: number, stopIndex: number): number {\n const threshold = 0.1;\n\n let cutIndex = startIndex;\n const entryAtCut = entriesWithIdleRemoved[cutIndex];\n const timings = Helpers.Timing.eventTimingsMicroSeconds(entryAtCut);\n let cutTime = (timings.startTime + timings.endTime) / 2;\n let usedTime = 0;\n const step = Math.sign(stopIndex - startIndex);\n for (let i = startIndex; i !== stopIndex; i += step) {\n const task = entriesWithIdleRemoved[i];\n const taskTimings = Helpers.Timing.eventTimingsMicroSeconds(task);\n const taskTime = (taskTimings.startTime + taskTimings.endTime) / 2;\n const interval = Math.abs(cutTime - taskTime);\n if (usedTime < threshold * interval) {\n cutIndex = i;\n cutTime = taskTime;\n usedTime = 0;\n }\n usedTime += taskTimings.duration;\n }\n return cutIndex;\n }\n const rightIndex = findLowUtilizationRegion(entriesWithIdleRemoved.length - 1, 0);\n const leftIndex = findLowUtilizationRegion(0, rightIndex);\n const leftTimings = Helpers.Timing.eventTimingsMicroSeconds(entriesWithIdleRemoved[leftIndex]);\n const rightTimings = Helpers.Timing.eventTimingsMicroSeconds(entriesWithIdleRemoved[rightIndex]);\n\n let leftTime = leftTimings.startTime;\n let rightTime = rightTimings.endTime;\n const zoomedInSpan = rightTime - leftTime;\n\n if (zoomedInSpan < traceBounds.range * 0.1) {\n // If the area we have chosen to zoom into is less than 10% of the entire\n // span, we bail and show the entire trace. It would not be so useful to\n // the user to zoom in on such a small area; we assume they have\n // purposefully recorded a trace that contains empty periods of time.\n return traceBounds;\n }\n\n // Adjust the left time down by 5%, and the right time up by 5%, so that\n // we give the range we want to zoom a bit of breathing space. At the\n // same time, ensure that we do not stray beyond the bounds of the\n // min/max time of the entire trace.\n leftTime = Types.Timing.MicroSeconds(Math.max(leftTime - 0.05 * zoomedInSpan, traceBounds.min));\n rightTime = Types.Timing.MicroSeconds(Math.min(rightTime + 0.05 * zoomedInSpan, traceBounds.max));\n\n return {\n min: leftTime,\n max: rightTime,\n range: Types.Timing.MicroSeconds(rightTime - leftTime),\n };\n}\n"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Copyright 2023 The Chromium Authors. All rights reserved.
|
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
import * as SDK from '../../../core/sdk/sdk.js';
|
|
5
|
+
export async function forNewRecording(recordStartTime) {
|
|
6
|
+
try {
|
|
7
|
+
const cpuThrottlingManager = SDK.CPUThrottlingManager.CPUThrottlingManager.instance();
|
|
8
|
+
// If the CPU Throttling manager has yet to have its primary page target
|
|
9
|
+
// set, it will block on the call to get the current hardware concurrency
|
|
10
|
+
// until it does. At this point where the user has recorded a trace, that
|
|
11
|
+
// target should have been set. So if it doesn't have it set, we instead
|
|
12
|
+
// just bail and don't store the hardware concurrency (this is only
|
|
13
|
+
// metadata, not mission critical information).
|
|
14
|
+
// We also race this call against a 1s timeout, because sometimes this call
|
|
15
|
+
// can hang (unsure exactly why) and we do not want to block parsing for
|
|
16
|
+
// too long as a result.
|
|
17
|
+
function getConcurrencyOrTimeout() {
|
|
18
|
+
return Promise.race([
|
|
19
|
+
SDK.CPUThrottlingManager.CPUThrottlingManager.instance().getHardwareConcurrency(),
|
|
20
|
+
new Promise(resolve => {
|
|
21
|
+
setTimeout(() => resolve(undefined), 1_000);
|
|
22
|
+
}),
|
|
23
|
+
]);
|
|
24
|
+
}
|
|
25
|
+
const hardwareConcurrency = cpuThrottlingManager.hasPrimaryPageTargetSet() ? await getConcurrencyOrTimeout() : undefined;
|
|
26
|
+
const cpuThrottling = SDK.CPUThrottlingManager.CPUThrottlingManager.instance().cpuThrottlingRate();
|
|
27
|
+
const networkConditions = SDK.NetworkManager.MultitargetNetworkManager.instance().networkConditions();
|
|
28
|
+
const networkTitle = typeof networkConditions.title === 'function' ? networkConditions.title() : networkConditions.title;
|
|
29
|
+
return {
|
|
30
|
+
source: 'DevTools',
|
|
31
|
+
startTime: recordStartTime ? new Date(recordStartTime).toJSON() : undefined,
|
|
32
|
+
cpuThrottling,
|
|
33
|
+
networkThrottling: networkTitle,
|
|
34
|
+
hardwareConcurrency,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// If anything went wrong, it does not really matter. The impact is that we
|
|
39
|
+
// will not save the metadata when we save the trace to disk, but that is
|
|
40
|
+
// not really important, so just return empty object and move on
|
|
41
|
+
return {};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=Metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Metadata.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/extras/Metadata.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,GAAG,MAAM,0BAA0B,CAAC;AAGhD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,eAAwB;IAC5D,IAAI;QACF,MAAM,oBAAoB,GAAG,GAAG,CAAC,oBAAoB,CAAC,oBAAoB,CAAC,QAAQ,EAAE,CAAC;QAEtF,wEAAwE;QACxE,yEAAyE;QACzE,yEAAyE;QACzE,wEAAwE;QACxE,mEAAmE;QACnE,+CAA+C;QAC/C,2EAA2E;QAC3E,wEAAwE;QACxE,wBAAwB;QACxB,SAAS,uBAAuB;YAC9B,OAAO,OAAO,CAAC,IAAI,CAAC;gBAClB,GAAG,CAAC,oBAAoB,CAAC,oBAAoB,CAAC,QAAQ,EAAE,CAAC,sBAAsB,EAAE;gBACjF,IAAI,OAAO,CAAY,OAAO,CAAC,EAAE;oBAC/B,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC;gBAC9C,CAAC,CAAC;aACH,CAAC,CAAC;QACL,CAAC;QAED,MAAM,mBAAmB,GACrB,oBAAoB,CAAC,uBAAuB,EAAE,CAAC,CAAC,CAAC,MAAM,uBAAuB,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACjG,MAAM,aAAa,GAAG,GAAG,CAAC,oBAAoB,CAAC,oBAAoB,CAAC,QAAQ,EAAE,CAAC,iBAAiB,EAAE,CAAC;QACnG,MAAM,iBAAiB,GAAG,GAAG,CAAC,cAAc,CAAC,yBAAyB,CAAC,QAAQ,EAAE,CAAC,iBAAiB,EAAE,CAAC;QACtG,MAAM,YAAY,GACd,OAAO,iBAAiB,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC;QAExG,OAAO;YACL,MAAM,EAAE,UAAU;YAClB,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS;YAC3E,aAAa;YACb,iBAAiB,EAAE,YAAY;YAC/B,mBAAmB;SACpB,CAAC;KACH;IAAC,MAAM;QACN,2EAA2E;QAC3E,yEAAyE;QACzE,gEAAgE;QAChE,OAAO,EAAE,CAAC;KACX;AACH,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 SDK from '../../../core/sdk/sdk.js';\nimport type * as Types from '../types/types.js';\n\nexport async function forNewRecording(recordStartTime?: number): Promise<Types.File.MetaData> {\n try {\n const cpuThrottlingManager = SDK.CPUThrottlingManager.CPUThrottlingManager.instance();\n\n // If the CPU Throttling manager has yet to have its primary page target\n // set, it will block on the call to get the current hardware concurrency\n // until it does. At this point where the user has recorded a trace, that\n // target should have been set. So if it doesn't have it set, we instead\n // just bail and don't store the hardware concurrency (this is only\n // metadata, not mission critical information).\n // We also race this call against a 1s timeout, because sometimes this call\n // can hang (unsure exactly why) and we do not want to block parsing for\n // too long as a result.\n function getConcurrencyOrTimeout(): Promise<number|undefined> {\n return Promise.race([\n SDK.CPUThrottlingManager.CPUThrottlingManager.instance().getHardwareConcurrency(),\n new Promise<undefined>(resolve => {\n setTimeout(() => resolve(undefined), 1_000);\n }),\n ]);\n }\n\n const hardwareConcurrency =\n cpuThrottlingManager.hasPrimaryPageTargetSet() ? await getConcurrencyOrTimeout() : undefined;\n const cpuThrottling = SDK.CPUThrottlingManager.CPUThrottlingManager.instance().cpuThrottlingRate();\n const networkConditions = SDK.NetworkManager.MultitargetNetworkManager.instance().networkConditions();\n const networkTitle =\n typeof networkConditions.title === 'function' ? networkConditions.title() : networkConditions.title;\n\n return {\n source: 'DevTools',\n startTime: recordStartTime ? new Date(recordStartTime).toJSON() : undefined, // ISO-8601 timestamp\n cpuThrottling,\n networkThrottling: networkTitle,\n hardwareConcurrency,\n };\n } catch {\n // If anything went wrong, it does not really matter. The impact is that we\n // will not save the metadata when we save the trace to disk, but that is\n // not really important, so just return empty object and move on\n return {};\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"compilerOptions":{"composite":true,"outDir":".","baseUrl":".","rootDir":"../../../../../../../front_end/models/trace/extras"},"files":["../../../../../../../front_end/models/trace/extras/extras.ts"],"references":[{"path":"./extras-tsconfig.json"}]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"allowJs": true,
|
|
4
|
+
"checkJs": true,
|
|
5
|
+
"composite": true,
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"experimentalDecorators": true,
|
|
8
|
+
"forceConsistentCasingInFileNames": true,
|
|
9
|
+
"inlineSources": true,
|
|
10
|
+
"lib": [
|
|
11
|
+
"esnext",
|
|
12
|
+
"dom",
|
|
13
|
+
"dom.iterable"
|
|
14
|
+
],
|
|
15
|
+
"module": "esnext",
|
|
16
|
+
"noEmitOnError": true,
|
|
17
|
+
"noFallthroughCasesInSwitch": true,
|
|
18
|
+
"noImplicitOverride": true,
|
|
19
|
+
"noImplicitReturns": true,
|
|
20
|
+
"noUnusedLocals": false,
|
|
21
|
+
"outDir": ".",
|
|
22
|
+
"rootDir": "../../../../../../../front_end/models/trace/extras",
|
|
23
|
+
"skipLibCheck": true,
|
|
24
|
+
"sourceMap": true,
|
|
25
|
+
"strict": true,
|
|
26
|
+
"target": "esnext",
|
|
27
|
+
"tsBuildInfoFile": "devtools_entrypoint-bundle-typescript-tsconfig.json.tsbuildinfo",
|
|
28
|
+
"typeRoots": [],
|
|
29
|
+
"useUnknownInCatchVariables": false
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"../../../../../../../front_end/models/trace/extras/extras.ts",
|
|
33
|
+
"../../../../../../../front_end/legacy/legacy-defs.d.ts",
|
|
34
|
+
"../../../../../../../front_end/global_typings/global_defs.d.ts",
|
|
35
|
+
"../../../../../../../front_end/global_typings/request_idle_callback.d.ts",
|
|
36
|
+
"../../../../../../../node_modules/@types/filesystem/index.d.ts",
|
|
37
|
+
"../../../../../../../node_modules/@webgpu/types/dist/index.d.ts"
|
|
38
|
+
],
|
|
39
|
+
"references": [
|
|
40
|
+
{
|
|
41
|
+
"path": "./extras-tsconfig.json"
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|