@paulirish/trace_engine 0.0.44 → 0.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.tmp/tsbuildinfo/tsconfig.tsbuildinfo +1 -1
- package/core/platform/ArrayUtilities.d.ts +1 -1
- package/core/platform/ArrayUtilities.js.map +1 -1
- package/core/platform/DOMUtilities.js +1 -1
- package/core/platform/DOMUtilities.js.map +1 -1
- package/core/platform/MimeType.js.map +1 -1
- package/core/platform/NumberUtilities.js.map +1 -1
- package/core/platform/ServerTiming.d.ts +2 -2
- package/core/platform/ServerTiming.js.map +1 -1
- package/core/platform/StringUtilities.js +1 -1
- package/core/platform/StringUtilities.js.map +1 -1
- package/core/platform/Timing.d.ts +0 -1
- package/core/platform/Timing.js +0 -3
- package/core/platform/Timing.js.map +1 -1
- package/core/platform/TypedArrayUtilities.js +3 -2
- package/core/platform/TypedArrayUtilities.js.map +1 -1
- package/generated/protocol.d.ts +71 -4
- package/locales/af.json +544 -1
- package/locales/am.json +544 -1
- package/locales/ar.json +544 -1
- package/locales/as.json +544 -1
- package/locales/az.json +544 -1
- package/locales/be.json +544 -1
- package/locales/bg.json +544 -1
- package/locales/bn.json +544 -1
- package/locales/bs.json +544 -1
- package/locales/ca.json +544 -1
- package/locales/cs.json +544 -1
- package/locales/cy.json +544 -1
- package/locales/da.json +544 -1
- package/locales/de.json +544 -1
- package/locales/el.json +544 -1
- package/locales/en-GB.json +544 -1
- package/locales/en-US.json +561 -15
- package/locales/en-XL.json +561 -15
- package/locales/es-419.json +544 -1
- package/locales/es.json +544 -1
- package/locales/et.json +544 -1
- package/locales/eu.json +544 -1
- package/locales/fa.json +544 -1
- package/locales/fi.json +544 -1
- package/locales/fil.json +544 -1
- package/locales/fr-CA.json +544 -1
- package/locales/fr.json +544 -1
- package/locales/gl.json +544 -1
- package/locales/gu.json +544 -1
- package/locales/he.json +545 -2
- package/locales/hi.json +544 -1
- package/locales/hr.json +544 -1
- package/locales/hu.json +544 -1
- package/locales/hy.json +544 -1
- package/locales/id.json +544 -1
- package/locales/is.json +544 -1
- package/locales/it.json +544 -1
- package/locales/ja.json +544 -1
- package/locales/ka.json +544 -1
- package/locales/kk.json +544 -1
- package/locales/km.json +544 -1
- package/locales/kn.json +544 -1
- package/locales/ko.json +544 -1
- package/locales/ky.json +544 -1
- package/locales/lo.json +544 -1
- package/locales/lt.json +544 -1
- package/locales/lv.json +544 -1
- package/locales/mk.json +544 -1
- package/locales/ml.json +544 -1
- package/locales/mn.json +544 -1
- package/locales/mr.json +544 -1
- package/locales/ms.json +544 -1
- package/locales/my.json +544 -1
- package/locales/ne.json +544 -1
- package/locales/nl.json +544 -1
- package/locales/no.json +544 -1
- package/locales/or.json +544 -1
- package/locales/pa.json +544 -1
- package/locales/pl.json +544 -1
- package/locales/pt-PT.json +544 -1
- package/locales/pt.json +544 -1
- package/locales/ro.json +544 -1
- package/locales/ru.json +544 -1
- package/locales/si.json +544 -1
- package/locales/sk.json +544 -1
- package/locales/sl.json +544 -1
- package/locales/sq.json +544 -1
- package/locales/sr-Latn.json +544 -1
- package/locales/sr.json +544 -1
- package/locales/sv.json +544 -1
- package/locales/sw.json +544 -1
- package/locales/ta.json +544 -1
- package/locales/te.json +544 -1
- package/locales/th.json +544 -1
- package/locales/tr.json +544 -1
- package/locales/uk.json +544 -1
- package/locales/ur.json +544 -1
- package/locales/uz.json +544 -1
- package/locales/vi.json +544 -1
- package/locales/zh-HK.json +544 -1
- package/locales/zh-TW.json +544 -1
- package/locales/zh.json +544 -1
- package/locales/zu.json +544 -1
- package/models/cpu_profile/CPUProfileDataModel.js +10 -10
- package/models/cpu_profile/CPUProfileDataModel.js.map +1 -1
- package/models/trace/LanternComputationData.js.map +1 -1
- package/models/trace/ModelImpl.d.ts +1 -0
- package/models/trace/ModelImpl.js +1 -0
- package/models/trace/ModelImpl.js.map +1 -1
- package/models/trace/Processor.js +16 -11
- package/models/trace/Processor.js.map +1 -1
- package/models/trace/extras/FetchNodes.d.ts +1 -1
- package/models/trace/extras/FetchNodes.js +3 -3
- package/models/trace/extras/FetchNodes.js.map +1 -1
- package/models/trace/extras/ScriptDuplication.d.ts +34 -0
- package/models/trace/extras/ScriptDuplication.js +178 -0
- package/models/trace/extras/ScriptDuplication.js.map +1 -0
- package/models/trace/extras/StackTraceForEvent.js +25 -44
- package/models/trace/extras/StackTraceForEvent.js.map +1 -1
- package/models/trace/extras/ThirdParties.js +1 -0
- package/models/trace/extras/ThirdParties.js.map +1 -1
- package/models/trace/extras/TraceTree.d.ts +5 -2
- package/models/trace/extras/TraceTree.js +47 -17
- package/models/trace/extras/TraceTree.js.map +1 -1
- package/models/trace/extras/extras-tsconfig.json +1 -1
- 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 -1
- package/models/trace/handlers/AnimationFramesHandler.js.map +1 -1
- package/models/trace/handlers/AsyncJSCallsHandler.js.map +1 -1
- package/models/trace/handlers/AuctionWorkletsHandler.js.map +1 -1
- package/models/trace/handlers/ExtensionTraceDataHandler.d.ts +1 -1
- package/models/trace/handlers/ExtensionTraceDataHandler.js +2 -1
- package/models/trace/handlers/ExtensionTraceDataHandler.js.map +1 -1
- package/models/trace/handlers/FramesHandler.js.map +1 -1
- package/models/trace/handlers/ImagePaintingHandler.js +1 -1
- package/models/trace/handlers/ImagePaintingHandler.js.map +1 -1
- package/models/trace/handlers/InitiatorsHandler.js.map +1 -1
- package/models/trace/handlers/InvalidationsHandler.js.map +1 -1
- package/models/trace/handlers/LayoutShiftsHandler.js.map +1 -1
- package/models/trace/handlers/MetaHandler.d.ts +2 -2
- package/models/trace/handlers/MetaHandler.js +4 -6
- package/models/trace/handlers/MetaHandler.js.map +1 -1
- package/models/trace/handlers/ModelHandlers.d.ts +1 -0
- package/models/trace/handlers/ModelHandlers.js +1 -0
- package/models/trace/handlers/ModelHandlers.js.map +1 -1
- package/models/trace/handlers/NetworkRequestsHandler.d.ts +9 -0
- package/models/trace/handlers/NetworkRequestsHandler.js +6 -6
- package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -1
- package/models/trace/handlers/PageLoadMetricsHandler.js +1 -1
- package/models/trace/handlers/PageLoadMetricsHandler.js.map +1 -1
- package/models/trace/handlers/RendererHandler.js +3 -4
- package/models/trace/handlers/RendererHandler.js.map +1 -1
- package/models/trace/handlers/ScriptsHandler.d.ts +22 -0
- package/models/trace/handlers/ScriptsHandler.js +116 -0
- package/models/trace/handlers/ScriptsHandler.js.map +1 -0
- package/models/trace/handlers/UserTimingsHandler.d.ts +5 -0
- package/models/trace/handlers/UserTimingsHandler.js +16 -0
- package/models/trace/handlers/UserTimingsHandler.js.map +1 -1
- package/models/trace/handlers/WorkersHandler.js.map +1 -1
- package/models/trace/handlers/handlers-tsconfig.json +1 -0
- package/models/trace/handlers/helpers.d.ts +5 -1
- package/models/trace/handlers/helpers.js +28 -4
- package/models/trace/handlers/helpers.js.map +1 -1
- package/models/trace/helpers/Network.d.ts +1 -0
- package/models/trace/helpers/Network.js +8 -3
- package/models/trace/helpers/Network.js.map +1 -1
- package/models/trace/helpers/SamplesIntegrator.d.ts +8 -1
- package/models/trace/helpers/SamplesIntegrator.js +42 -2
- package/models/trace/helpers/SamplesIntegrator.js.map +1 -1
- package/models/trace/helpers/Timing.js.map +1 -1
- package/models/trace/helpers/Trace.d.ts +7 -10
- package/models/trace/helpers/Trace.js +25 -10
- package/models/trace/helpers/Trace.js.map +1 -1
- package/models/trace/insights/CLSCulprits.d.ts +12 -12
- package/models/trace/insights/CLSCulprits.js +15 -4
- package/models/trace/insights/CLSCulprits.js.map +1 -1
- package/models/trace/insights/Common.d.ts +7 -1
- package/models/trace/insights/Common.js +9 -3
- package/models/trace/insights/Common.js.map +1 -1
- package/models/trace/insights/DOMSize.d.ts +8 -8
- package/models/trace/insights/DOMSize.js +2 -1
- package/models/trace/insights/DOMSize.js.map +1 -1
- package/models/trace/insights/DocumentLatency.d.ts +11 -11
- package/models/trace/insights/DocumentLatency.js +2 -1
- package/models/trace/insights/DocumentLatency.js.map +1 -1
- package/models/trace/insights/DuplicateJavaScript.d.ts +18 -0
- package/models/trace/insights/DuplicateJavaScript.js +49 -0
- package/models/trace/insights/DuplicateJavaScript.js.map +1 -0
- package/models/trace/insights/FontDisplay.d.ts +4 -4
- package/models/trace/insights/FontDisplay.js +2 -1
- package/models/trace/insights/FontDisplay.js.map +1 -1
- package/models/trace/insights/ForcedReflow.d.ts +5 -5
- package/models/trace/insights/ForcedReflow.js +4 -1
- package/models/trace/insights/ForcedReflow.js.map +1 -1
- package/models/trace/insights/ImageDelivery.d.ts +19 -15
- package/models/trace/insights/ImageDelivery.js +26 -20
- package/models/trace/insights/ImageDelivery.js.map +1 -1
- package/models/trace/insights/InteractionToNextPaint.d.ts +8 -8
- package/models/trace/insights/InteractionToNextPaint.js +3 -2
- package/models/trace/insights/InteractionToNextPaint.js.map +1 -1
- package/models/trace/insights/LCPDiscovery.d.ts +9 -9
- package/models/trace/insights/LCPDiscovery.js +6 -3
- package/models/trace/insights/LCPDiscovery.js.map +1 -1
- package/models/trace/insights/LCPPhases.d.ts +15 -10
- package/models/trace/insights/LCPPhases.js +11 -4
- package/models/trace/insights/LCPPhases.js.map +1 -1
- package/models/trace/insights/Models.d.ts +2 -1
- package/models/trace/insights/Models.js +2 -1
- package/models/trace/insights/Models.js.map +1 -1
- package/models/trace/insights/NetworkDependencyTree.d.ts +33 -0
- package/models/trace/insights/NetworkDependencyTree.js +141 -0
- package/models/trace/insights/NetworkDependencyTree.js.map +1 -0
- package/models/trace/insights/RenderBlocking.d.ts +5 -5
- package/models/trace/insights/RenderBlocking.js +2 -1
- package/models/trace/insights/RenderBlocking.js.map +1 -1
- package/models/trace/insights/SlowCSSSelector.d.ts +8 -8
- package/models/trace/insights/SlowCSSSelector.js +4 -2
- package/models/trace/insights/SlowCSSSelector.js.map +1 -1
- package/models/trace/insights/ThirdParties.d.ts +6 -6
- package/models/trace/insights/ThirdParties.js +8 -5
- package/models/trace/insights/ThirdParties.js.map +1 -1
- package/models/trace/insights/Viewport.d.ts +2 -2
- package/models/trace/insights/Viewport.js +2 -1
- package/models/trace/insights/Viewport.js.map +1 -1
- package/models/trace/insights/insights-tsconfig.json +2 -1
- package/models/trace/insights/types.d.ts +25 -3
- package/models/trace/insights/types.js.map +1 -1
- package/models/trace/lantern/core/NetworkAnalyzer.d.ts +2 -2
- package/models/trace/lantern/core/NetworkAnalyzer.js +2 -2
- package/models/trace/lantern/core/NetworkAnalyzer.js.map +1 -1
- package/models/trace/lantern/graph/BaseNode.d.ts +1 -1
- package/models/trace/lantern/graph/BaseNode.js.map +1 -1
- package/models/trace/lantern/graph/CPUNode.js +1 -1
- package/models/trace/lantern/graph/CPUNode.js.map +1 -1
- package/models/trace/lantern/graph/NetworkNode.js +1 -1
- package/models/trace/lantern/graph/NetworkNode.js.map +1 -1
- package/models/trace/lantern/graph/PageDependencyGraph.d.ts +2 -2
- package/models/trace/lantern/graph/PageDependencyGraph.js.map +1 -1
- package/models/trace/lantern/metrics/Metric.js.map +1 -1
- package/models/trace/lantern/metrics/TotalBlockingTime.d.ts +2 -2
- package/models/trace/lantern/metrics/TotalBlockingTime.js.map +1 -1
- package/models/trace/lantern/types/Lantern.d.ts +2 -2
- package/models/trace/lantern/types/Lantern.js.map +1 -1
- package/models/trace/trace-tsconfig.json +3 -3
- package/models/trace/trace.d.ts +1 -2
- package/models/trace/trace.js +1 -2
- package/models/trace/trace.js.map +1 -1
- package/models/trace/types/Configuration.d.ts +10 -0
- package/models/trace/types/Configuration.js.map +1 -1
- package/models/trace/types/Extensions.d.ts +1 -1
- package/models/trace/types/Extensions.js.map +1 -1
- package/models/trace/types/TraceEvents.d.ts +87 -4
- package/models/trace/types/TraceEvents.js +20 -0
- package/models/trace/types/TraceEvents.js.map +1 -1
- package/package.json +1 -1
- package/test/test-trace-engine.mjs +3 -2
- package/models/trace/extras/TimelineJSProfile.d.ts +0 -13
- package/models/trace/extras/TimelineJSProfile.js +0 -60
- package/models/trace/extras/TimelineJSProfile.js.map +0 -1
- package/models/trace/insights/LongCriticalNetworkTree.d.ts +0 -22
- package/models/trace/insights/LongCriticalNetworkTree.js +0 -40
- package/models/trace/insights/LongCriticalNetworkTree.js.map +0 -1
- package/models/trace/root-causes/LayoutShift.d.ts +0 -125
- package/models/trace/root-causes/LayoutShift.js +0 -519
- package/models/trace/root-causes/LayoutShift.js.map +0 -1
- package/models/trace/root-causes/RootCauses.d.ts +0 -15
- package/models/trace/root-causes/RootCauses.js +0 -12
- package/models/trace/root-causes/RootCauses.js.map +0 -1
- package/models/trace/root-causes/bundle-tsconfig.json +0 -1
- package/models/trace/root-causes/devtools_entrypoint-bundle-typescript-tsconfig.json +0 -43
- package/models/trace/root-causes/root-causes-tsconfig.json +0 -56
- package/models/trace/root-causes/root-causes.d.ts +0 -1
- package/models/trace/root-causes/root-causes.js +0 -5
- package/models/trace/root-causes/root-causes.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseNode.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/graph/BaseNode.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Core from '../core/core.js';\nimport type * as Lantern from '../types/types.js';\n\nimport type {CPUNode} from './CPUNode.js';\nimport type {NetworkNode} from './NetworkNode.js';\n\n/**\n * A union of all types derived from BaseNode, allowing type check discrimination\n * based on `node.type`. If a new node type is created, it should be added here.\n */\nexport type Node<T = Lantern.AnyNetworkObject> = CPUNode<T>|NetworkNode<T>;\n\n/**\n * @fileoverview This class encapsulates logic for handling resources and tasks used to model the\n * execution dependency graph of the page. A node has a unique identifier and can depend on other\n * nodes/be depended on. The construction of the graph maintains some important invariants that are\n * inherent to the model:\n *\n * 1. The graph is a DAG, there are no cycles.\n * 2. There is always a root node upon which all other nodes eventually depend.\n *\n * This allows particular optimizations in this class so that we do no need to check for cycles as\n * these methods are called and we can always start traversal at the root node.\n */\n\nclass BaseNode<T = Lantern.AnyNetworkObject> {\n static types = {\n NETWORK: 'network',\n CPU: 'cpu',\n } as const;\n\n _id: string;\n _isMainDocument: boolean;\n dependents: Node[];\n dependencies: Node[];\n\n constructor(id: string) {\n this._id = id;\n this._isMainDocument = false;\n this.dependents = [];\n this.dependencies = [];\n }\n\n get id(): string {\n return this._id;\n }\n\n get type(): 'network'|'cpu' {\n throw new Core.LanternError('Unimplemented');\n }\n\n /**\n * In microseconds\n */\n get startTime(): number {\n throw new Core.LanternError('Unimplemented');\n }\n\n /**\n * In microseconds\n */\n get endTime(): number {\n throw new Core.LanternError('Unimplemented');\n }\n\n setIsMainDocument(value: boolean): void {\n this._isMainDocument = value;\n }\n\n isMainDocument(): boolean {\n return this._isMainDocument;\n }\n\n getDependents(): Node[] {\n return this.dependents.slice();\n }\n\n getNumberOfDependents(): number {\n return this.dependents.length;\n }\n\n getDependencies(): Node[] {\n return this.dependencies.slice();\n }\n\n getNumberOfDependencies(): number {\n return this.dependencies.length;\n }\n\n getRootNode(): Node<T> {\n let rootNode = this as BaseNode as Node;\n while (rootNode.dependencies.length) {\n rootNode = rootNode.dependencies[0];\n }\n\n return rootNode;\n }\n\n addDependent(node: Node): void {\n node.addDependency(this as BaseNode as Node);\n }\n\n addDependency(node: Node): void {\n // @ts-expect-error - in checkJs, ts doesn't know that CPUNode and NetworkNode *are* BaseNodes.\n if (node === this) {\n throw new Core.LanternError('Cannot add dependency on itself');\n }\n\n if (this.dependencies.includes(node)) {\n return;\n }\n\n node.dependents.push(this as BaseNode as Node);\n this.dependencies.push(node);\n }\n\n removeDependent(node: Node): void {\n node.removeDependency(this as BaseNode as Node);\n }\n\n removeDependency(node: Node): void {\n if (!this.dependencies.includes(node)) {\n return;\n }\n\n const thisIndex = node.dependents.indexOf(this as BaseNode as Node);\n node.dependents.splice(thisIndex, 1);\n this.dependencies.splice(this.dependencies.indexOf(node), 1);\n }\n\n // Unused in devtools, but used in LH.\n removeAllDependencies(): void {\n for (const node of this.dependencies.slice()) {\n this.removeDependency(node);\n }\n }\n\n /**\n * Computes whether the given node is anywhere in the dependency graph of this node.\n * While this method can prevent cycles, it walks the graph and should be used sparingly.\n * Nodes are always considered dependent on themselves for the purposes of cycle detection.\n */\n isDependentOn(node: BaseNode<T>): boolean {\n let isDependentOnNode = false;\n this.traverse(\n currentNode => {\n if (isDependentOnNode) {\n return;\n }\n isDependentOnNode = currentNode === node;\n },\n currentNode => {\n // If we've already found the dependency, don't traverse further.\n if (isDependentOnNode) {\n return [];\n }\n // Otherwise, traverse the dependencies.\n return currentNode.getDependencies();\n });\n\n return isDependentOnNode;\n }\n\n /**\n * Clones the node's information without adding any dependencies/dependents.\n */\n cloneWithoutRelationships(): Node<T> {\n const node = new BaseNode(this.id) as Node<T>;\n node.setIsMainDocument(this._isMainDocument);\n return node;\n }\n\n /**\n * Clones the entire graph connected to this node filtered by the optional predicate. If a node is\n * included by the predicate, all nodes along the paths between the node and the root will be included. If the\n * node this was called on is not included in the resulting filtered graph, the method will throw.\n *\n * This does not clone NetworkNode's `record` or `rawRecord` fields. It may be reasonable to clone the former,\n * to assist in graph construction, but the latter should never be cloned as one constraint of Lantern is that\n * the underlying data records are accessible for plain object reference equality checks.\n */\n cloneWithRelationships(predicate?: (arg0: Node) => boolean): Node {\n const rootNode = this.getRootNode();\n\n const idsToIncludedClones = new Map<string, Node>();\n\n // Walk down dependents.\n rootNode.traverse(node => {\n if (idsToIncludedClones.has(node.id)) {\n return;\n }\n\n if (predicate === undefined) {\n // No condition for entry, so clone every node.\n idsToIncludedClones.set(node.id, node.cloneWithoutRelationships());\n return;\n }\n\n if (predicate(node)) {\n // Node included, so walk back up dependencies, cloning nodes from here back to the root.\n node.traverse(\n node => idsToIncludedClones.set(node.id, node.cloneWithoutRelationships()),\n // Dependencies already cloned have already cloned ancestors, so no need to visit again.\n node => node.dependencies.filter(parent => !idsToIncludedClones.has(parent.id)),\n );\n }\n });\n\n // Copy dependencies between nodes.\n rootNode.traverse(originalNode => {\n const clonedNode = idsToIncludedClones.get(originalNode.id);\n if (!clonedNode) {\n return;\n }\n\n for (const dependency of originalNode.dependencies) {\n const clonedDependency = idsToIncludedClones.get(dependency.id);\n if (!clonedDependency) {\n throw new Core.LanternError('Dependency somehow not cloned');\n }\n clonedNode.addDependency(clonedDependency);\n }\n });\n\n const clonedThisNode = idsToIncludedClones.get(this.id);\n if (!clonedThisNode) {\n throw new Core.LanternError('Cloned graph missing node');\n }\n return clonedThisNode;\n }\n\n /**\n * Traverses all connected nodes in BFS order, calling `callback` exactly once\n * on each. `traversalPath` is the shortest (though not necessarily unique)\n * path from `node` to the root of the iteration.\n *\n * The `getNextNodes` function takes a visited node and returns which nodes to\n * visit next. It defaults to returning the node's dependents.\n */\n traverse(callback: (node: Node<T>, traversalPath: Node<T>[]) => void, getNextNodes?: (arg0: Node<T>) => Node<T>[]):\n void {\n for (const {node, traversalPath} of this.traverseGenerator(getNextNodes)) {\n callback(node, traversalPath);\n }\n }\n\n /**\n * @see BaseNode.traverse\n */\n // clang-format off\n *traverseGenerator(getNextNodes?: (arg0: Node) => Node[]):\n Generator<{node: Node, traversalPath: Node[]}, void, unknown> {\n // clang-format on\n if (!getNextNodes) {\n getNextNodes = node => node.getDependents();\n }\n\n // @ts-expect-error - only traverses graphs of Node, so force tsc to treat `this` as one\n const queue: Node[][] = [[this]];\n const visited = new Set([this.id]);\n\n while (queue.length) {\n // @ts-expect-error - queue has length so it's guaranteed to have an item\n const traversalPath: Node[] = queue.shift();\n const node = traversalPath[0];\n yield {node, traversalPath};\n\n for (const nextNode of getNextNodes(node)) {\n if (visited.has(nextNode.id)) {\n continue;\n }\n visited.add(nextNode.id);\n\n queue.push([nextNode, ...traversalPath]);\n }\n }\n }\n\n /**\n * Returns whether the given node has a cycle in its dependent graph by performing a DFS.\n */\n static hasCycle(node: Node, direction: 'dependents'|'dependencies'|'both' = 'both'): boolean {\n // Checking 'both' is the default entrypoint to recursively check both directions\n if (direction === 'both') {\n return BaseNode.hasCycle(node, 'dependents') || BaseNode.hasCycle(node, 'dependencies');\n }\n\n const visited = new Set();\n const currentPath: BaseNode[] = [];\n const toVisit = [node];\n const depthAdded = new Map([[node, 0]]);\n\n // Keep going while we have nodes to visit in the stack\n while (toVisit.length) {\n // Get the last node in the stack (DFS uses stack, not queue)\n // @ts-expect-error - toVisit has length so it's guaranteed to have an item\n const currentNode: BaseNode = toVisit.pop();\n\n // We've hit a cycle if the node we're visiting is in our current dependency path\n if (currentPath.includes(currentNode)) {\n return true;\n }\n // If we've already visited the node, no need to revisit it\n if (visited.has(currentNode)) {\n continue;\n }\n\n // Since we're visiting this node, clear out any nodes in our path that we had to backtrack\n // @ts-expect-error\n while (currentPath.length > depthAdded.get(currentNode)) {\n currentPath.pop();\n }\n\n // Update our data structures to reflect that we're adding this node to our path\n visited.add(currentNode);\n currentPath.push(currentNode);\n\n // Add all of its dependents to our toVisit stack\n const nodesToExplore = direction === 'dependents' ? currentNode.dependents : currentNode.dependencies;\n for (const nextNode of nodesToExplore) {\n if (toVisit.includes(nextNode)) {\n continue;\n }\n toVisit.push(nextNode);\n depthAdded.set(nextNode, currentPath.length);\n }\n }\n\n return false;\n }\n\n canDependOn(node: Node): boolean {\n return node.startTime <= this.startTime;\n }\n}\n\nexport {BaseNode};\n"]}
|
|
1
|
+
{"version":3,"file":"BaseNode.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/graph/BaseNode.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Core from '../core/core.js';\nimport type * as Lantern from '../types/types.js';\n\nimport type {CPUNode} from './CPUNode.js';\nimport type {NetworkNode} from './NetworkNode.js';\n\n/**\n * A union of all types derived from BaseNode, allowing type check discrimination\n * based on `node.type`. If a new node type is created, it should be added here.\n */\nexport type Node<T = Lantern.AnyNetworkObject> = CPUNode<T>|NetworkNode<T>;\n\n/**\n * @fileoverview This class encapsulates logic for handling resources and tasks used to model the\n * execution dependency graph of the page. A node has a unique identifier and can depend on other\n * nodes/be depended on. The construction of the graph maintains some important invariants that are\n * inherent to the model:\n *\n * 1. The graph is a DAG, there are no cycles.\n * 2. There is always a root node upon which all other nodes eventually depend.\n *\n * This allows particular optimizations in this class so that we do no need to check for cycles as\n * these methods are called and we can always start traversal at the root node.\n */\n\nclass BaseNode<T = Lantern.AnyNetworkObject> {\n static types = {\n NETWORK: 'network',\n CPU: 'cpu',\n } as const;\n\n _id: string;\n _isMainDocument: boolean;\n dependents: Node[];\n dependencies: Node[];\n\n constructor(id: string) {\n this._id = id;\n this._isMainDocument = false;\n this.dependents = [];\n this.dependencies = [];\n }\n\n get id(): string {\n return this._id;\n }\n\n get type(): 'network'|'cpu' {\n throw new Core.LanternError('Unimplemented');\n }\n\n /**\n * In microseconds\n */\n get startTime(): number {\n throw new Core.LanternError('Unimplemented');\n }\n\n /**\n * In microseconds\n */\n get endTime(): number {\n throw new Core.LanternError('Unimplemented');\n }\n\n setIsMainDocument(value: boolean): void {\n this._isMainDocument = value;\n }\n\n isMainDocument(): boolean {\n return this._isMainDocument;\n }\n\n getDependents(): Node[] {\n return this.dependents.slice();\n }\n\n getNumberOfDependents(): number {\n return this.dependents.length;\n }\n\n getDependencies(): Node[] {\n return this.dependencies.slice();\n }\n\n getNumberOfDependencies(): number {\n return this.dependencies.length;\n }\n\n getRootNode(): Node<T> {\n let rootNode = this as BaseNode as Node;\n while (rootNode.dependencies.length) {\n rootNode = rootNode.dependencies[0];\n }\n\n return rootNode;\n }\n\n addDependent(node: Node): void {\n node.addDependency(this as BaseNode as Node);\n }\n\n addDependency(node: Node): void {\n // @ts-expect-error - in checkJs, ts doesn't know that CPUNode and NetworkNode *are* BaseNodes.\n if (node === this) {\n throw new Core.LanternError('Cannot add dependency on itself');\n }\n\n if (this.dependencies.includes(node)) {\n return;\n }\n\n node.dependents.push(this as BaseNode as Node);\n this.dependencies.push(node);\n }\n\n removeDependent(node: Node): void {\n node.removeDependency(this as BaseNode as Node);\n }\n\n removeDependency(node: Node): void {\n if (!this.dependencies.includes(node)) {\n return;\n }\n\n const thisIndex = node.dependents.indexOf(this as BaseNode as Node);\n node.dependents.splice(thisIndex, 1);\n this.dependencies.splice(this.dependencies.indexOf(node), 1);\n }\n\n // Unused in devtools, but used in LH.\n removeAllDependencies(): void {\n for (const node of this.dependencies.slice()) {\n this.removeDependency(node);\n }\n }\n\n /**\n * Computes whether the given node is anywhere in the dependency graph of this node.\n * While this method can prevent cycles, it walks the graph and should be used sparingly.\n * Nodes are always considered dependent on themselves for the purposes of cycle detection.\n */\n isDependentOn(node: BaseNode<T>): boolean {\n let isDependentOnNode = false;\n this.traverse(\n currentNode => {\n if (isDependentOnNode) {\n return;\n }\n isDependentOnNode = currentNode === node;\n },\n currentNode => {\n // If we've already found the dependency, don't traverse further.\n if (isDependentOnNode) {\n return [];\n }\n // Otherwise, traverse the dependencies.\n return currentNode.getDependencies();\n });\n\n return isDependentOnNode;\n }\n\n /**\n * Clones the node's information without adding any dependencies/dependents.\n */\n cloneWithoutRelationships(): Node<T> {\n const node = new BaseNode(this.id) as Node<T>;\n node.setIsMainDocument(this._isMainDocument);\n return node;\n }\n\n /**\n * Clones the entire graph connected to this node filtered by the optional predicate. If a node is\n * included by the predicate, all nodes along the paths between the node and the root will be included. If the\n * node this was called on is not included in the resulting filtered graph, the method will throw.\n *\n * This does not clone NetworkNode's `record` or `rawRecord` fields. It may be reasonable to clone the former,\n * to assist in graph construction, but the latter should never be cloned as one constraint of Lantern is that\n * the underlying data records are accessible for plain object reference equality checks.\n */\n cloneWithRelationships(predicate?: (arg0: Node) => boolean): Node {\n const rootNode = this.getRootNode();\n\n const idsToIncludedClones = new Map<string, Node>();\n\n // Walk down dependents.\n rootNode.traverse(node => {\n if (idsToIncludedClones.has(node.id)) {\n return;\n }\n\n if (predicate === undefined) {\n // No condition for entry, so clone every node.\n idsToIncludedClones.set(node.id, node.cloneWithoutRelationships());\n return;\n }\n\n if (predicate(node)) {\n // Node included, so walk back up dependencies, cloning nodes from here back to the root.\n node.traverse(\n node => idsToIncludedClones.set(node.id, node.cloneWithoutRelationships()),\n // Dependencies already cloned have already cloned ancestors, so no need to visit again.\n node => node.dependencies.filter(parent => !idsToIncludedClones.has(parent.id)),\n );\n }\n });\n\n // Copy dependencies between nodes.\n rootNode.traverse(originalNode => {\n const clonedNode = idsToIncludedClones.get(originalNode.id);\n if (!clonedNode) {\n return;\n }\n\n for (const dependency of originalNode.dependencies) {\n const clonedDependency = idsToIncludedClones.get(dependency.id);\n if (!clonedDependency) {\n throw new Core.LanternError('Dependency somehow not cloned');\n }\n clonedNode.addDependency(clonedDependency);\n }\n });\n\n const clonedThisNode = idsToIncludedClones.get(this.id);\n if (!clonedThisNode) {\n throw new Core.LanternError('Cloned graph missing node');\n }\n return clonedThisNode;\n }\n\n /**\n * Traverses all connected nodes in BFS order, calling `callback` exactly once\n * on each. `traversalPath` is the shortest (though not necessarily unique)\n * path from `node` to the root of the iteration.\n *\n * The `getNextNodes` function takes a visited node and returns which nodes to\n * visit next. It defaults to returning the node's dependents.\n */\n traverse(\n callback: (node: Node<T>, traversalPath: Array<Node<T>>) => void,\n getNextNodes?: (arg0: Node<T>) => Array<Node<T>>): void {\n for (const {node, traversalPath} of this.traverseGenerator(getNextNodes)) {\n callback(node, traversalPath);\n }\n }\n\n /**\n * @see BaseNode.traverse\n */\n // clang-format off\n *traverseGenerator(getNextNodes?: (arg0: Node) => Node[]):\n Generator<{node: Node, traversalPath: Node[]}, void, unknown> {\n // clang-format on\n if (!getNextNodes) {\n getNextNodes = node => node.getDependents();\n }\n\n // @ts-expect-error - only traverses graphs of Node, so force tsc to treat `this` as one\n const queue: Node[][] = [[this]];\n const visited = new Set([this.id]);\n\n while (queue.length) {\n // @ts-expect-error - queue has length so it's guaranteed to have an item\n const traversalPath: Node[] = queue.shift();\n const node = traversalPath[0];\n yield {node, traversalPath};\n\n for (const nextNode of getNextNodes(node)) {\n if (visited.has(nextNode.id)) {\n continue;\n }\n visited.add(nextNode.id);\n\n queue.push([nextNode, ...traversalPath]);\n }\n }\n }\n\n /**\n * Returns whether the given node has a cycle in its dependent graph by performing a DFS.\n */\n static hasCycle(node: Node, direction: 'dependents'|'dependencies'|'both' = 'both'): boolean {\n // Checking 'both' is the default entrypoint to recursively check both directions\n if (direction === 'both') {\n return BaseNode.hasCycle(node, 'dependents') || BaseNode.hasCycle(node, 'dependencies');\n }\n\n const visited = new Set();\n const currentPath: BaseNode[] = [];\n const toVisit = [node];\n const depthAdded = new Map([[node, 0]]);\n\n // Keep going while we have nodes to visit in the stack\n while (toVisit.length) {\n // Get the last node in the stack (DFS uses stack, not queue)\n // @ts-expect-error - toVisit has length so it's guaranteed to have an item\n const currentNode: BaseNode = toVisit.pop();\n\n // We've hit a cycle if the node we're visiting is in our current dependency path\n if (currentPath.includes(currentNode)) {\n return true;\n }\n // If we've already visited the node, no need to revisit it\n if (visited.has(currentNode)) {\n continue;\n }\n\n // Since we're visiting this node, clear out any nodes in our path that we had to backtrack\n // @ts-expect-error\n while (currentPath.length > depthAdded.get(currentNode)) {\n currentPath.pop();\n }\n\n // Update our data structures to reflect that we're adding this node to our path\n visited.add(currentNode);\n currentPath.push(currentNode);\n\n // Add all of its dependents to our toVisit stack\n const nodesToExplore = direction === 'dependents' ? currentNode.dependents : currentNode.dependencies;\n for (const nextNode of nodesToExplore) {\n if (toVisit.includes(nextNode)) {\n continue;\n }\n toVisit.push(nextNode);\n depthAdded.set(nextNode, currentPath.length);\n }\n }\n\n return false;\n }\n\n canDependOn(node: Node): boolean {\n return node.startTime <= this.startTime;\n }\n}\n\nexport {BaseNode};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CPUNode.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/graph/CPUNode.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAI7B,OAAO,EAAC,QAAQ,EAAC,MAAM,eAAe,CAAC;AAEvC,MAAM,OAAsC,SAAQ,QAAW;IAC7D,MAAM,CAAqB;IAC3B,YAAY,CAAuB;IACnC,cAAc,CAAmB;IAEjC,YAAY,WAA+B,EAAE,cAAoC,EAAE,EAAE,cAAuB;QAC1G,MAAM,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,IAAI,WAAW,CAAC,EAAE,EAAE,CAAC;QACtD,KAAK,CAAC,MAAM,CAAC,CAAC;QAEd,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC;QAC1B,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;QAChC,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACvC,CAAC;IAED,IAAa,IAAI;QACf,OAAO,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC;IAC5B,CAAC;IAED,IAAa,SAAS;QACpB,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;IACxB,CAAC;IAED,IAAa,OAAO;QAClB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,cAAc,CAAC;QAC7B,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IAC1C,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC;IACvC,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IAC9D,CAAC;IAED;;OAEG;IACH,qBAAqB;QACnB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtC,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBACpC,SAAS;YACX,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"CPUNode.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/graph/CPUNode.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAI7B,OAAO,EAAC,QAAQ,EAAC,MAAM,eAAe,CAAC;AAEvC,MAAM,OAAsC,SAAQ,QAAW;IAC7D,MAAM,CAAqB;IAC3B,YAAY,CAAuB;IACnC,cAAc,CAAmB;IAEjC,YAAY,WAA+B,EAAE,cAAoC,EAAE,EAAE,cAAuB;QAC1G,MAAM,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,IAAI,WAAW,CAAC,EAAE,EAAE,CAAC;QACtD,KAAK,CAAC,MAAM,CAAC,CAAC;QAEd,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC;QAC1B,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;QAChC,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACvC,CAAC;IAED,IAAa,IAAI;QACf,OAAO,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC;IAC5B,CAAC;IAED,IAAa,SAAS;QACpB,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;IACxB,CAAC;IAED,IAAa,OAAO;QAClB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,cAAc,CAAC;QAC7B,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IAC1C,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC;IACvC,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IAC9D,CAAC;IAED;;OAEG;IACH,qBAAqB;QACnB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtC,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBACpC,SAAS;YACX,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC;gBAC1B,SAAS;YACX,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAEQ,yBAAyB;QAChC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;IAC1E,CAAC;CACF;AAED,OAAO,EAAC,OAAO,EAAC,CAAC","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport type * as Lantern from '../types/types.js';\n\nimport {BaseNode} from './BaseNode.js';\n\nclass CPUNode<T = Lantern.AnyNetworkObject> extends BaseNode<T> {\n _event: Lantern.TraceEvent;\n _childEvents: Lantern.TraceEvent[];\n correctedEndTs: number|undefined;\n\n constructor(parentEvent: Lantern.TraceEvent, childEvents: Lantern.TraceEvent[] = [], correctedEndTs?: number) {\n const nodeId = `${parentEvent.tid}.${parentEvent.ts}`;\n super(nodeId);\n\n this._event = parentEvent;\n this._childEvents = childEvents;\n this.correctedEndTs = correctedEndTs;\n }\n\n override get type(): 'cpu' {\n return BaseNode.types.CPU;\n }\n\n override get startTime(): number {\n return this._event.ts;\n }\n\n override get endTime(): number {\n if (this.correctedEndTs) {\n return this.correctedEndTs;\n }\n return this._event.ts + this._event.dur;\n }\n\n get duration(): number {\n return this.endTime - this.startTime;\n }\n\n get event(): Lantern.TraceEvent {\n return this._event;\n }\n\n get childEvents(): Lantern.TraceEvent[] {\n return this._childEvents;\n }\n\n /**\n * Returns true if this node contains a Layout task.\n */\n didPerformLayout(): boolean {\n return this._childEvents.some(evt => evt.name === 'Layout');\n }\n\n /**\n * Returns the script URLs that had their EvaluateScript events occur in this task.\n */\n getEvaluateScriptURLs(): Set<string> {\n const urls = new Set<string>();\n for (const event of this._childEvents) {\n if (event.name !== 'EvaluateScript') {\n continue;\n }\n if (!event.args.data?.url) {\n continue;\n }\n urls.add(event.args.data.url);\n }\n\n return urls;\n }\n\n override cloneWithoutRelationships(): CPUNode {\n return new CPUNode(this._event, this._childEvents, this.correctedEndTs);\n }\n}\n\nexport {CPUNode};\n"]}
|
|
@@ -47,7 +47,7 @@ class NetworkNode extends BaseNode {
|
|
|
47
47
|
return this._request;
|
|
48
48
|
}
|
|
49
49
|
get initiatorType() {
|
|
50
|
-
return this._request.initiator
|
|
50
|
+
return this._request.initiator.type;
|
|
51
51
|
}
|
|
52
52
|
get fromDiskCache() {
|
|
53
53
|
return Boolean(this._request.fromDiskCache);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NetworkNode.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/graph/NetworkNode.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAI7B,OAAO,EAAC,QAAQ,EAAC,MAAM,eAAe,CAAC;AAEvC,MAAM,mBAAmB,GAAG;IAC1B,MAAM,EAAS,4EAA4E;IAC3F,MAAM,EAAS,kFAAkF;IACjG,QAAQ,EAAO,sEAAsE;IACrF,MAAM,EAAS,qDAAqD;IACpE,YAAY,EAAG,mEAAmE;IAClF,kBAAkB;CACnB,CAAC;AAEF;;;;;;;;;GASG;AACH,SAAS,oBAAoB,CAAC,QAAgB;IAC5C,sBAAsB;IACtB,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC/F,OAAO,mBAAmB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,WAA0C,SAAQ,QAAW;IACjE,QAAQ,CAA4B;IAEpC,YAAY,cAAyC;QACnD,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAChC,IAAI,CAAC,QAAQ,GAAG,cAAc,CAAC;IACjC,CAAC;IAED,IAAa,IAAI;QACf,OAAO,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;IAChC,CAAC;IAED,IAAa,SAAS;QACpB,OAAO,IAAI,CAAC,QAAQ,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAChD,CAAC;IAED,IAAa,OAAO;QAClB,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,GAAG,IAAI,CAAC;IAC7C,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAyB,CAAC;IACjD,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"NetworkNode.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/graph/NetworkNode.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAI7B,OAAO,EAAC,QAAQ,EAAC,MAAM,eAAe,CAAC;AAEvC,MAAM,mBAAmB,GAAG;IAC1B,MAAM,EAAS,4EAA4E;IAC3F,MAAM,EAAS,kFAAkF;IACjG,QAAQ,EAAO,sEAAsE;IACrF,MAAM,EAAS,qDAAqD;IACpE,YAAY,EAAG,mEAAmE;IAClF,kBAAkB;CACnB,CAAC;AAEF;;;;;;;;;GASG;AACH,SAAS,oBAAoB,CAAC,QAAgB;IAC5C,sBAAsB;IACtB,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC/F,OAAO,mBAAmB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,WAA0C,SAAQ,QAAW;IACjE,QAAQ,CAA4B;IAEpC,YAAY,cAAyC;QACnD,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAChC,IAAI,CAAC,QAAQ,GAAG,cAAc,CAAC;IACjC,CAAC;IAED,IAAa,IAAI;QACf,OAAO,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;IAChC,CAAC;IAED,IAAa,SAAS;QACpB,OAAO,IAAI,CAAC,QAAQ,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAChD,CAAC;IAED,IAAa,OAAO;QAClB,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,GAAG,IAAI,CAAC;IAC7C,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAyB,CAAC;IACjD,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC;IACtC,CAAC;IAED,IAAI,aAAa;QACf,OAAO,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,oBAAoB;QACtB,iEAAiE;QACjE,OAAO,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;YAC9C,uFAAuF;YACvF,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1D,CAAC;IAED;;;OAGG;IACH,IAAI,gBAAgB;QAClB,OAAO,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,oBAAoB,CAAC;IACzD,CAAC;IAED,yBAAyB;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,KAAK,QAAQ,CAAC;QACzD,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,KAAK,UAAU,CAAC;QAC7D,MAAM,gBAAgB,GAAG,QAAQ,KAAK,MAAM,IAAI,QAAQ,CAAC;QACzD,MAAM,oBAAoB,GAAG,QAAQ,KAAK,MAAM,IAAI,UAAU,CAAC;QAC/D,OAAO,QAAQ,KAAK,UAAU,IAAI,gBAAgB,IAAI,oBAAoB,CAAC;IAC7E,CAAC;IAEQ,yBAAyB;QAChC,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,OAAO,EAAC,WAAW,EAAC,CAAC","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport type * as Lantern from '../types/types.js';\n\nimport {BaseNode} from './BaseNode.js';\n\nconst NON_NETWORK_SCHEMES = [\n 'blob', // @see https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL\n 'data', // @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs\n 'intent', // @see https://developer.chrome.com/docs/multidevice/android/intents/\n 'file', // @see https://en.wikipedia.org/wiki/File_URI_scheme\n 'filesystem', // @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystem\n 'chrome-extension',\n];\n\n/**\n * Note: the `protocol` field from CDP can be 'h2', 'http', (not 'https'!) or it'll be url's scheme.\n * https://source.chromium.org/chromium/chromium/src/+/main:content/browser/devtools/protocol/network_handler.cc;l=598-611;drc=56d4a9a9deb30be73adcee8737c73bcb2a5ab64f\n * However, a `new URL(href).protocol` has a colon suffix.\n * https://url.spec.whatwg.org/#dom-url-protocol\n * A URL's `scheme` is specced as the `protocol` sans-colon, but isn't exposed on a URL object.\n * This method can take all 3 of these string types as a parameter.\n *\n * @param protocol Either a networkRequest's `protocol` per CDP or a `new URL(href).protocol`\n */\nfunction isNonNetworkProtocol(protocol: string): boolean {\n // Strip off any colon\n const urlScheme = protocol.includes(':') ? protocol.slice(0, protocol.indexOf(':')) : protocol;\n return NON_NETWORK_SCHEMES.includes(urlScheme);\n}\n\nclass NetworkNode<T = Lantern.AnyNetworkObject> extends BaseNode<T> {\n _request: Lantern.NetworkRequest<T>;\n\n constructor(networkRequest: Lantern.NetworkRequest<T>) {\n super(networkRequest.requestId);\n this._request = networkRequest;\n }\n\n override get type(): 'network' {\n return BaseNode.types.NETWORK;\n }\n\n override get startTime(): number {\n return this._request.rendererStartTime * 1000;\n }\n\n override get endTime(): number {\n return this._request.networkEndTime * 1000;\n }\n\n get rawRequest(): Readonly<T> {\n return this._request.rawRequest as Required<T>;\n }\n\n get request(): Lantern.NetworkRequest<T> {\n return this._request;\n }\n\n get initiatorType(): string {\n return this._request.initiator.type;\n }\n\n get fromDiskCache(): boolean {\n return Boolean(this._request.fromDiskCache);\n }\n\n get isNonNetworkProtocol(): boolean {\n // The 'protocol' field in devtools a string more like a `scheme`\n return isNonNetworkProtocol(this.request.protocol) ||\n // But `protocol` can fail to be populated if the request fails, so fallback to scheme.\n isNonNetworkProtocol(this.request.parsedURL.scheme);\n }\n\n /**\n * Returns whether this network request can be downloaded without a TCP connection.\n * During simulation we treat data coming in over a network connection separately from on-device data.\n */\n get isConnectionless(): boolean {\n return this.fromDiskCache || this.isNonNetworkProtocol;\n }\n\n hasRenderBlockingPriority(): boolean {\n const priority = this._request.priority;\n const isScript = this._request.resourceType === 'Script';\n const isDocument = this._request.resourceType === 'Document';\n const isBlockingScript = priority === 'High' && isScript;\n const isBlockingHtmlImport = priority === 'High' && isDocument;\n return priority === 'VeryHigh' || isBlockingScript || isBlockingHtmlImport;\n }\n\n override cloneWithoutRelationships(): NetworkNode<T> {\n const node = new NetworkNode(this._request);\n node.setIsMainDocument(this._isMainDocument);\n return node;\n }\n}\n\nexport {NetworkNode};\n"]}
|
|
@@ -3,9 +3,9 @@ import type { Node } from './BaseNode.js';
|
|
|
3
3
|
import { CPUNode } from './CPUNode.js';
|
|
4
4
|
import { NetworkNode } from './NetworkNode.js';
|
|
5
5
|
interface NetworkNodeOutput {
|
|
6
|
-
nodes:
|
|
6
|
+
nodes: NetworkNode[];
|
|
7
7
|
idToNodeMap: Map<string, NetworkNode>;
|
|
8
|
-
urlToNodeMap: Map<string,
|
|
8
|
+
urlToNodeMap: Map<string, NetworkNode[]>;
|
|
9
9
|
frameIdToNodeMap: Map<string, NetworkNode | null>;
|
|
10
10
|
}
|
|
11
11
|
declare class PageDependencyGraph {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PageDependencyGraph.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/graph/PageDependencyGraph.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Core from '../core/core.js';\nimport type * as Lantern from '../types/types.js';\n\nimport type {Node} from './BaseNode.js';\nimport {CPUNode} from './CPUNode.js';\nimport {NetworkNode} from './NetworkNode.js';\n\n// COMPAT: m71+ We added RunTask to `disabled-by-default-lighthouse`\nconst SCHEDULABLE_TASK_TITLE_LH = 'RunTask';\n// m69-70 DoWork is different and we now need RunTask, see https://bugs.chromium.org/p/chromium/issues/detail?id=871204#c11\nconst SCHEDULABLE_TASK_TITLE_ALT1 = 'ThreadControllerImpl::RunTask';\n// In m66-68 refactored to this task title, https://crrev.com/c/883346\nconst SCHEDULABLE_TASK_TITLE_ALT2 = 'ThreadControllerImpl::DoWork';\n// m65 and earlier\nconst SCHEDULABLE_TASK_TITLE_ALT3 = 'TaskQueueManager::ProcessTaskFromWorkQueue';\n\ninterface NetworkNodeOutput {\n nodes: Array<NetworkNode>;\n idToNodeMap: Map<string, NetworkNode>;\n urlToNodeMap: Map<string, Array<NetworkNode>>;\n frameIdToNodeMap: Map<string, NetworkNode|null>;\n}\n\n// Shorter tasks have negligible impact on simulation results.\nconst SIGNIFICANT_DUR_THRESHOLD_MS = 10;\n\n// TODO: video files tend to be enormous and throw off all graph traversals, move this ignore\n// into estimation logic when we use the dependency graph for other purposes.\nconst IGNORED_MIME_TYPES_REGEX = /^video/;\n\nclass PageDependencyGraph {\n static getNetworkInitiators(request: Lantern.NetworkRequest): string[] {\n if (!request.initiator) {\n return [];\n }\n if (request.initiator.url) {\n return [request.initiator.url];\n }\n if (request.initiator.type === 'script') {\n // Script initiators have the stack of callFrames from all functions that led to this request.\n // If async stacks are enabled, then the stack will also have the parent functions that asynchronously\n // led to this request chained in the `parent` property.\n const scriptURLs = new Set<string>();\n let stack = request.initiator.stack;\n while (stack) {\n const callFrames = stack.callFrames || [];\n for (const frame of callFrames) {\n if (frame.url) {\n scriptURLs.add(frame.url);\n }\n }\n\n stack = stack.parent;\n }\n\n return Array.from(scriptURLs);\n }\n\n return [];\n }\n\n static getNetworkNodeOutput(networkRequests: Lantern.NetworkRequest[]): NetworkNodeOutput {\n const nodes: Array<NetworkNode> = [];\n const idToNodeMap = new Map<string, NetworkNode>();\n const urlToNodeMap = new Map<string, Array<NetworkNode>>();\n const frameIdToNodeMap = new Map<string, NetworkNode|null>();\n\n networkRequests.forEach(request => {\n if (IGNORED_MIME_TYPES_REGEX.test(request.mimeType)) {\n return;\n }\n if (request.fromWorker) {\n return;\n }\n\n // Network requestIds can be duplicated for an unknown reason\n // Suffix all subsequent requests with `:duplicate` until it's unique\n // NOTE: This should never happen with modern NetworkRequest library, but old fixtures\n // might still have this issue.\n while (idToNodeMap.has(request.requestId)) {\n request.requestId += ':duplicate';\n }\n\n const node = new NetworkNode(request);\n nodes.push(node);\n\n const urlList = urlToNodeMap.get(request.url) || [];\n urlList.push(node);\n\n idToNodeMap.set(request.requestId, node);\n urlToNodeMap.set(request.url, urlList);\n\n // If the request was for the root document of an iframe, save an entry in our\n // map so we can link up the task `args.data.frame` dependencies later in graph creation.\n if (request.frameId && request.resourceType === 'Document' && request.documentURL === request.url) {\n // If there's ever any ambiguity, permanently set the value to `false` to avoid loops in the graph.\n const value = frameIdToNodeMap.has(request.frameId) ? null : node;\n frameIdToNodeMap.set(request.frameId, value);\n }\n });\n\n return {nodes, idToNodeMap, urlToNodeMap, frameIdToNodeMap};\n }\n\n static isScheduleableTask(evt: Lantern.TraceEvent): boolean {\n return evt.name === SCHEDULABLE_TASK_TITLE_LH || evt.name === SCHEDULABLE_TASK_TITLE_ALT1 ||\n evt.name === SCHEDULABLE_TASK_TITLE_ALT2 || evt.name === SCHEDULABLE_TASK_TITLE_ALT3;\n }\n\n /**\n * There should *always* be at least one top level event, having 0 typically means something is\n * drastically wrong with the trace and we should just give up early and loudly.\n */\n static assertHasToplevelEvents(events: Lantern.TraceEvent[]): void {\n const hasToplevelTask = events.some(this.isScheduleableTask);\n if (!hasToplevelTask) {\n throw new Core.LanternError('Could not find any top level events');\n }\n }\n\n static getCPUNodes(mainThreadEvents: Lantern.TraceEvent[]): CPUNode[] {\n const nodes: CPUNode[] = [];\n let i = 0;\n\n PageDependencyGraph.assertHasToplevelEvents(mainThreadEvents);\n\n while (i < mainThreadEvents.length) {\n const evt = mainThreadEvents[i];\n i++;\n\n // Skip all trace events that aren't schedulable tasks with sizable duration\n if (!PageDependencyGraph.isScheduleableTask(evt) || !evt.dur) {\n continue;\n }\n\n let correctedEndTs: number|undefined = undefined;\n\n // Capture all events that occurred within the task\n const children: Lantern.TraceEvent[] = [];\n for (const endTime = evt.ts + evt.dur; i < mainThreadEvents.length && mainThreadEvents[i].ts < endTime; i++) {\n const event = mainThreadEvents[i];\n\n // Temporary fix for a Chrome bug where some RunTask events can be overlapping.\n // We correct that here be ensuring each RunTask ends at least 1 microsecond before the next\n // https://github.com/GoogleChrome/lighthouse/issues/15896\n // https://issues.chromium.org/issues/329678173\n if (PageDependencyGraph.isScheduleableTask(event) && event.dur) {\n correctedEndTs = event.ts - 1;\n break;\n }\n\n children.push(event);\n }\n\n nodes.push(new CPUNode(evt, children, correctedEndTs));\n }\n\n return nodes;\n }\n\n static linkNetworkNodes(rootNode: NetworkNode, networkNodeOutput: NetworkNodeOutput): void {\n networkNodeOutput.nodes.forEach(node => {\n const directInitiatorRequest = node.request.initiatorRequest || rootNode.request;\n const directInitiatorNode = networkNodeOutput.idToNodeMap.get(directInitiatorRequest.requestId) || rootNode;\n const canDependOnInitiator = !directInitiatorNode.isDependentOn(node) && node.canDependOn(directInitiatorNode);\n const initiators = PageDependencyGraph.getNetworkInitiators(node.request);\n if (initiators.length) {\n initiators.forEach(initiator => {\n const parentCandidates = networkNodeOutput.urlToNodeMap.get(initiator) || [];\n // Only add the edge if the parent is unambiguous with valid timing and isn't circular.\n if (parentCandidates.length === 1 && parentCandidates[0].startTime <= node.startTime &&\n !parentCandidates[0].isDependentOn(node)) {\n node.addDependency(parentCandidates[0]);\n } else if (canDependOnInitiator) {\n directInitiatorNode.addDependent(node);\n }\n });\n } else if (canDependOnInitiator) {\n directInitiatorNode.addDependent(node);\n }\n\n // Make sure the nodes are attached to the graph if the initiator information was invalid.\n if (node !== rootNode && node.getDependencies().length === 0 && node.canDependOn(rootNode)) {\n node.addDependency(rootNode);\n }\n\n if (!node.request.redirects) {\n return;\n }\n\n const redirects = [...node.request.redirects, node.request];\n for (let i = 1; i < redirects.length; i++) {\n const redirectNode = networkNodeOutput.idToNodeMap.get(redirects[i - 1].requestId);\n const actualNode = networkNodeOutput.idToNodeMap.get(redirects[i].requestId);\n if (actualNode && redirectNode) {\n actualNode.addDependency(redirectNode);\n }\n }\n });\n }\n\n static linkCPUNodes(rootNode: Node, networkNodeOutput: NetworkNodeOutput, cpuNodes: CPUNode[]): void {\n const linkableResourceTypes = new Set<Lantern.ResourceType|undefined>([\n 'XHR',\n 'Fetch',\n 'Script',\n ]);\n\n function addDependentNetworkRequest(cpuNode: CPUNode, reqId: string): void {\n const networkNode = networkNodeOutput.idToNodeMap.get(reqId);\n if (!networkNode ||\n // Ignore all network nodes that started before this CPU task started\n // A network request that started earlier could not possibly have been started by this task\n networkNode.startTime <= cpuNode.startTime) {\n return;\n }\n const {request} = networkNode;\n const resourceType = request.resourceType || request.redirectDestination?.resourceType;\n if (!linkableResourceTypes.has(resourceType)) {\n // We only link some resources to CPU nodes because we observe LCP simulation\n // regressions when including images, etc.\n return;\n }\n cpuNode.addDependent(networkNode);\n }\n\n /**\n * If the node has an associated frameId, then create a dependency on the root document request\n * for the frame. The task obviously couldn't have started before the frame was even downloaded.\n */\n function addDependencyOnFrame(cpuNode: CPUNode, frameId: string|undefined): void {\n if (!frameId) {\n return;\n }\n const networkNode = networkNodeOutput.frameIdToNodeMap.get(frameId);\n if (!networkNode) {\n return;\n }\n // Ignore all network nodes that started after this CPU task started\n // A network request that started after could not possibly be required this task\n if (networkNode.startTime >= cpuNode.startTime) {\n return;\n }\n cpuNode.addDependency(networkNode);\n }\n\n function addDependencyOnUrl(cpuNode: CPUNode, url: string): void {\n if (!url) {\n return;\n }\n // Allow network requests that end up to 100ms before the task started\n // Some script evaluations can start before the script finishes downloading\n const minimumAllowableTimeSinceNetworkNodeEnd = -100 * 1000;\n const candidates = networkNodeOutput.urlToNodeMap.get(url) || [];\n\n let minCandidate = null;\n let minDistance = Infinity;\n // Find the closest request that finished before this CPU task started\n for (const candidate of candidates) {\n // Explicitly ignore all requests that started after this CPU node\n // A network request that started after this task started cannot possibly be a dependency\n if (cpuNode.startTime <= candidate.startTime) {\n return;\n }\n\n const distance = cpuNode.startTime - candidate.endTime;\n if (distance >= minimumAllowableTimeSinceNetworkNodeEnd && distance < minDistance) {\n minCandidate = candidate;\n minDistance = distance;\n }\n }\n\n if (!minCandidate) {\n return;\n }\n cpuNode.addDependency(minCandidate);\n }\n\n const timers = new Map<string, CPUNode>();\n for (const node of cpuNodes) {\n for (const evt of node.childEvents) {\n if (!evt.args.data) {\n continue;\n }\n\n const argsUrl = evt.args.data.url;\n const stackTraceUrls = (evt.args.data.stackTrace || []).map(l => l.url).filter(Boolean);\n\n switch (evt.name) {\n case 'TimerInstall':\n // @ts-expect-error - 'TimerInstall' event means timerId exists.\n timers.set(evt.args.data.timerId, node);\n stackTraceUrls.forEach(url => addDependencyOnUrl(node, url));\n break;\n case 'TimerFire': {\n // @ts-expect-error - 'TimerFire' event means timerId exists.\n const installer = timers.get(evt.args.data.timerId);\n if (!installer || installer.endTime > node.startTime) {\n break;\n }\n installer.addDependent(node);\n break;\n }\n\n case 'InvalidateLayout':\n case 'ScheduleStyleRecalculation':\n addDependencyOnFrame(node, evt.args.data.frame);\n stackTraceUrls.forEach(url => addDependencyOnUrl(node, url));\n break;\n\n case 'EvaluateScript':\n addDependencyOnFrame(node, evt.args.data.frame);\n // @ts-expect-error - 'EvaluateScript' event means argsUrl is defined.\n addDependencyOnUrl(node, argsUrl);\n stackTraceUrls.forEach(url => addDependencyOnUrl(node, url));\n break;\n\n case 'XHRReadyStateChange':\n // Only create the dependency if the request was completed\n // 'XHRReadyStateChange' event means readyState is defined.\n if (evt.args.data.readyState !== 4) {\n break;\n }\n\n // @ts-expect-error - 'XHRReadyStateChange' event means argsUrl is defined.\n addDependencyOnUrl(node, argsUrl);\n stackTraceUrls.forEach(url => addDependencyOnUrl(node, url));\n break;\n\n case 'FunctionCall':\n case 'v8.compile':\n addDependencyOnFrame(node, evt.args.data.frame);\n // @ts-expect-error - events mean argsUrl is defined.\n addDependencyOnUrl(node, argsUrl);\n break;\n\n case 'ParseAuthorStyleSheet':\n addDependencyOnFrame(node, evt.args.data.frame);\n // @ts-expect-error - 'ParseAuthorStyleSheet' event means styleSheetUrl is defined.\n addDependencyOnUrl(node, evt.args.data.styleSheetUrl);\n break;\n\n case 'ResourceSendRequest':\n addDependencyOnFrame(node, evt.args.data.frame);\n // @ts-expect-error - 'ResourceSendRequest' event means requestId is defined.\n addDependentNetworkRequest(node, evt.args.data.requestId);\n stackTraceUrls.forEach(url => addDependencyOnUrl(node, url));\n break;\n }\n }\n\n // Nodes starting before the root node cannot depend on it.\n if (node.getNumberOfDependencies() === 0 && node.canDependOn(rootNode)) {\n node.addDependency(rootNode);\n }\n }\n\n // Second pass to prune the graph of short tasks.\n const minimumEvtDur = SIGNIFICANT_DUR_THRESHOLD_MS * 1000;\n let foundFirstLayout = false;\n let foundFirstPaint = false;\n let foundFirstParse = false;\n\n for (const node of cpuNodes) {\n // Don't prune if event is the first ParseHTML/Layout/Paint.\n // See https://github.com/GoogleChrome/lighthouse/issues/9627#issuecomment-526699524 for more.\n let isFirst = false;\n if (!foundFirstLayout && node.childEvents.some(evt => evt.name === 'Layout')) {\n isFirst = foundFirstLayout = true;\n }\n if (!foundFirstPaint && node.childEvents.some(evt => evt.name === 'Paint')) {\n isFirst = foundFirstPaint = true;\n }\n if (!foundFirstParse && node.childEvents.some(evt => evt.name === 'ParseHTML')) {\n isFirst = foundFirstParse = true;\n }\n\n if (isFirst || node.duration >= minimumEvtDur) {\n // Don't prune this node. The task is long / important so it will impact simulation.\n continue;\n }\n\n // Prune the node if it isn't highly connected to minimize graph size. Rewiring the graph\n // here replaces O(M + N) edges with (M * N) edges, which is fine if either M or N is at\n // most 1.\n if (node.getNumberOfDependencies() === 1 || node.getNumberOfDependents() <= 1) {\n PageDependencyGraph.pruneNode(node);\n }\n }\n }\n\n /**\n * Removes the given node from the graph, but retains all paths between its dependencies and\n * dependents.\n */\n static pruneNode(node: Node): void {\n const dependencies = node.getDependencies();\n const dependents = node.getDependents();\n for (const dependency of dependencies) {\n node.removeDependency(dependency);\n for (const dependent of dependents) {\n dependency.addDependent(dependent);\n }\n }\n for (const dependent of dependents) {\n node.removeDependent(dependent);\n }\n }\n\n /**\n * TODO: remove when CDT backend in Lighthouse is gone. Until then, this is a useful debugging tool\n * to find delta between using CDP or the trace to create the network requests.\n *\n * When a test fails using the trace backend, I enabled this debug method and copied the network\n * requests when CDP was used, then when trace is used, and diff'd them. This method helped\n * remove non-logical differences from the comparison (order of properties, slight rounding\n * discrepancies, removing object cycles, etc).\n *\n * When using for a unit test, make sure to do `.only` so you are getting what you expect.\n */\n static debugNormalizeRequests(lanternRequests: Lantern.NetworkRequest[]): void {\n for (const request of lanternRequests) {\n request.rendererStartTime = Math.round(request.rendererStartTime * 1000) / 1000;\n request.networkRequestTime = Math.round(request.networkRequestTime * 1000) / 1000;\n request.responseHeadersEndTime = Math.round(request.responseHeadersEndTime * 1000) / 1000;\n request.networkEndTime = Math.round(request.networkEndTime * 1000) / 1000;\n }\n\n for (const r of lanternRequests) {\n delete r.rawRequest;\n if (r.initiatorRequest) {\n // @ts-expect-error\n r.initiatorRequest = {id: r.initiatorRequest.requestId};\n }\n if (r.redirectDestination) {\n // @ts-expect-error\n r.redirectDestination = {id: r.redirectDestination.requestId};\n }\n if (r.redirectSource) {\n // @ts-expect-error\n r.redirectSource = {id: r.redirectSource.requestId};\n }\n if (r.redirects) {\n // @ts-expect-error\n r.redirects = r.redirects.map(r2 => r2.requestId);\n }\n }\n const requests: Lantern.NetworkRequest[] = lanternRequests\n .map(r => ({\n requestId: r.requestId,\n connectionId: r.connectionId,\n connectionReused: r.connectionReused,\n url: r.url,\n protocol: r.protocol,\n parsedURL: r.parsedURL,\n documentURL: r.documentURL,\n rendererStartTime: r.rendererStartTime,\n networkRequestTime: r.networkRequestTime,\n responseHeadersEndTime: r.responseHeadersEndTime,\n networkEndTime: r.networkEndTime,\n transferSize: r.transferSize,\n resourceSize: r.resourceSize,\n fromDiskCache: r.fromDiskCache,\n fromMemoryCache: r.fromMemoryCache,\n finished: r.finished,\n statusCode: r.statusCode,\n redirectSource: r.redirectSource,\n redirectDestination: r.redirectDestination,\n redirects: r.redirects,\n failed: r.failed,\n initiator: r.initiator,\n timing: r.timing ? {\n requestTime: r.timing.requestTime,\n proxyStart: r.timing.proxyStart,\n proxyEnd: r.timing.proxyEnd,\n dnsStart: r.timing.dnsStart,\n dnsEnd: r.timing.dnsEnd,\n connectStart: r.timing.connectStart,\n connectEnd: r.timing.connectEnd,\n sslStart: r.timing.sslStart,\n sslEnd: r.timing.sslEnd,\n workerStart: r.timing.workerStart,\n workerReady: r.timing.workerReady,\n workerFetchStart: r.timing.workerFetchStart,\n workerRespondWithSettled: r.timing.workerRespondWithSettled,\n sendStart: r.timing.sendStart,\n sendEnd: r.timing.sendEnd,\n pushStart: r.timing.pushStart,\n pushEnd: r.timing.pushEnd,\n receiveHeadersStart: r.timing.receiveHeadersStart,\n receiveHeadersEnd: r.timing.receiveHeadersEnd,\n } :\n r.timing,\n resourceType: r.resourceType,\n mimeType: r.mimeType,\n priority: r.priority,\n initiatorRequest: r.initiatorRequest,\n frameId: r.frameId,\n fromWorker: r.fromWorker,\n isLinkPreload: r.isLinkPreload,\n serverResponseTime: r.serverResponseTime,\n }))\n .filter(r => !r.fromWorker);\n\n const debug = requests;\n // Set breakpoint here.\n // Copy `debug` and compare with https://www.diffchecker.com/text-compare/\n // eslint-disable-next-line no-console\n console.log(debug);\n }\n\n static createGraph(\n mainThreadEvents: Lantern.TraceEvent[], networkRequests: Lantern.NetworkRequest[],\n url: Lantern.Simulation.URL): Node {\n // This is for debugging trace/devtoolslog network records.\n // const debug = PageDependencyGraph.debugNormalizeRequests(networkRequests);\n const networkNodeOutput = PageDependencyGraph.getNetworkNodeOutput(networkRequests);\n const cpuNodes = PageDependencyGraph.getCPUNodes(mainThreadEvents);\n const {requestedUrl, mainDocumentUrl} = url;\n if (!requestedUrl) {\n throw new Core.LanternError('requestedUrl is required to get the root request');\n }\n if (!mainDocumentUrl) {\n throw new Core.LanternError('mainDocumentUrl is required to get the main resource');\n }\n\n const rootRequest = Core.NetworkAnalyzer.findResourceForUrl(networkRequests, requestedUrl);\n if (!rootRequest) {\n throw new Core.LanternError('rootRequest not found');\n }\n const rootNode = networkNodeOutput.idToNodeMap.get(rootRequest.requestId);\n if (!rootNode) {\n throw new Core.LanternError('rootNode not found');\n }\n const mainDocumentRequest = Core.NetworkAnalyzer.findLastDocumentForUrl(networkRequests, mainDocumentUrl);\n if (!mainDocumentRequest) {\n throw new Core.LanternError('mainDocumentRequest not found');\n }\n const mainDocumentNode = networkNodeOutput.idToNodeMap.get(mainDocumentRequest.requestId);\n if (!mainDocumentNode) {\n throw new Core.LanternError('mainDocumentNode not found');\n }\n\n PageDependencyGraph.linkNetworkNodes(rootNode, networkNodeOutput);\n PageDependencyGraph.linkCPUNodes(rootNode, networkNodeOutput, cpuNodes);\n mainDocumentNode.setIsMainDocument(true);\n\n if (NetworkNode.hasCycle(rootNode)) {\n throw new Core.LanternError('Invalid dependency graph created, cycle detected');\n }\n\n return rootNode;\n }\n\n // Unused, but useful for debugging.\n static printGraph(rootNode: Node, widthInCharacters = 100): void {\n function padRight(str: string, target: number, padChar = ' '): string {\n return str + padChar.repeat(Math.max(target - str.length, 0));\n }\n\n const nodes: Node[] = [];\n rootNode.traverse(node => nodes.push(node));\n nodes.sort((a, b) => a.startTime - b.startTime);\n\n const min = nodes[0].startTime;\n const max = nodes.reduce((max, node) => Math.max(max, node.endTime), 0);\n\n const totalTime = max - min;\n const timePerCharacter = totalTime / widthInCharacters;\n nodes.forEach(node => {\n const offset = Math.round((node.startTime - min) / timePerCharacter);\n const length = Math.ceil((node.endTime - node.startTime) / timePerCharacter);\n const bar = padRight('', offset) + padRight('', length, '=');\n\n // @ts-expect-error -- disambiguate displayName from across possible Node types.\n const displayName = node.request ? node.request.url : node.type;\n // eslint-disable-next-line\n console.log(padRight(bar, widthInCharacters), `| ${displayName.slice(0, 30)}`);\n });\n }\n}\n\nexport {PageDependencyGraph};\n"]}
|
|
1
|
+
{"version":3,"file":"PageDependencyGraph.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/graph/PageDependencyGraph.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Core from '../core/core.js';\nimport type * as Lantern from '../types/types.js';\n\nimport type {Node} from './BaseNode.js';\nimport {CPUNode} from './CPUNode.js';\nimport {NetworkNode} from './NetworkNode.js';\n\n// COMPAT: m71+ We added RunTask to `disabled-by-default-lighthouse`\nconst SCHEDULABLE_TASK_TITLE_LH = 'RunTask';\n// m69-70 DoWork is different and we now need RunTask, see https://bugs.chromium.org/p/chromium/issues/detail?id=871204#c11\nconst SCHEDULABLE_TASK_TITLE_ALT1 = 'ThreadControllerImpl::RunTask';\n// In m66-68 refactored to this task title, https://crrev.com/c/883346\nconst SCHEDULABLE_TASK_TITLE_ALT2 = 'ThreadControllerImpl::DoWork';\n// m65 and earlier\nconst SCHEDULABLE_TASK_TITLE_ALT3 = 'TaskQueueManager::ProcessTaskFromWorkQueue';\n\ninterface NetworkNodeOutput {\n nodes: NetworkNode[];\n idToNodeMap: Map<string, NetworkNode>;\n urlToNodeMap: Map<string, NetworkNode[]>;\n frameIdToNodeMap: Map<string, NetworkNode|null>;\n}\n\n// Shorter tasks have negligible impact on simulation results.\nconst SIGNIFICANT_DUR_THRESHOLD_MS = 10;\n\n// TODO: video files tend to be enormous and throw off all graph traversals, move this ignore\n// into estimation logic when we use the dependency graph for other purposes.\nconst IGNORED_MIME_TYPES_REGEX = /^video/;\n\nclass PageDependencyGraph {\n static getNetworkInitiators(request: Lantern.NetworkRequest): string[] {\n if (!request.initiator) {\n return [];\n }\n if (request.initiator.url) {\n return [request.initiator.url];\n }\n if (request.initiator.type === 'script') {\n // Script initiators have the stack of callFrames from all functions that led to this request.\n // If async stacks are enabled, then the stack will also have the parent functions that asynchronously\n // led to this request chained in the `parent` property.\n const scriptURLs = new Set<string>();\n let stack = request.initiator.stack;\n while (stack) {\n const callFrames = stack.callFrames || [];\n for (const frame of callFrames) {\n if (frame.url) {\n scriptURLs.add(frame.url);\n }\n }\n\n stack = stack.parent;\n }\n\n return Array.from(scriptURLs);\n }\n\n return [];\n }\n\n static getNetworkNodeOutput(networkRequests: Lantern.NetworkRequest[]): NetworkNodeOutput {\n const nodes: NetworkNode[] = [];\n const idToNodeMap = new Map<string, NetworkNode>();\n const urlToNodeMap = new Map<string, NetworkNode[]>();\n const frameIdToNodeMap = new Map<string, NetworkNode|null>();\n\n networkRequests.forEach(request => {\n if (IGNORED_MIME_TYPES_REGEX.test(request.mimeType)) {\n return;\n }\n if (request.fromWorker) {\n return;\n }\n\n // Network requestIds can be duplicated for an unknown reason\n // Suffix all subsequent requests with `:duplicate` until it's unique\n // NOTE: This should never happen with modern NetworkRequest library, but old fixtures\n // might still have this issue.\n while (idToNodeMap.has(request.requestId)) {\n request.requestId += ':duplicate';\n }\n\n const node = new NetworkNode(request);\n nodes.push(node);\n\n const urlList = urlToNodeMap.get(request.url) || [];\n urlList.push(node);\n\n idToNodeMap.set(request.requestId, node);\n urlToNodeMap.set(request.url, urlList);\n\n // If the request was for the root document of an iframe, save an entry in our\n // map so we can link up the task `args.data.frame` dependencies later in graph creation.\n if (request.frameId && request.resourceType === 'Document' && request.documentURL === request.url) {\n // If there's ever any ambiguity, permanently set the value to `false` to avoid loops in the graph.\n const value = frameIdToNodeMap.has(request.frameId) ? null : node;\n frameIdToNodeMap.set(request.frameId, value);\n }\n });\n\n return {nodes, idToNodeMap, urlToNodeMap, frameIdToNodeMap};\n }\n\n static isScheduleableTask(evt: Lantern.TraceEvent): boolean {\n return evt.name === SCHEDULABLE_TASK_TITLE_LH || evt.name === SCHEDULABLE_TASK_TITLE_ALT1 ||\n evt.name === SCHEDULABLE_TASK_TITLE_ALT2 || evt.name === SCHEDULABLE_TASK_TITLE_ALT3;\n }\n\n /**\n * There should *always* be at least one top level event, having 0 typically means something is\n * drastically wrong with the trace and we should just give up early and loudly.\n */\n static assertHasToplevelEvents(events: Lantern.TraceEvent[]): void {\n const hasToplevelTask = events.some(this.isScheduleableTask);\n if (!hasToplevelTask) {\n throw new Core.LanternError('Could not find any top level events');\n }\n }\n\n static getCPUNodes(mainThreadEvents: Lantern.TraceEvent[]): CPUNode[] {\n const nodes: CPUNode[] = [];\n let i = 0;\n\n PageDependencyGraph.assertHasToplevelEvents(mainThreadEvents);\n\n while (i < mainThreadEvents.length) {\n const evt = mainThreadEvents[i];\n i++;\n\n // Skip all trace events that aren't schedulable tasks with sizable duration\n if (!PageDependencyGraph.isScheduleableTask(evt) || !evt.dur) {\n continue;\n }\n\n let correctedEndTs: number|undefined = undefined;\n\n // Capture all events that occurred within the task\n const children: Lantern.TraceEvent[] = [];\n for (const endTime = evt.ts + evt.dur; i < mainThreadEvents.length && mainThreadEvents[i].ts < endTime; i++) {\n const event = mainThreadEvents[i];\n\n // Temporary fix for a Chrome bug where some RunTask events can be overlapping.\n // We correct that here be ensuring each RunTask ends at least 1 microsecond before the next\n // https://github.com/GoogleChrome/lighthouse/issues/15896\n // https://issues.chromium.org/issues/329678173\n if (PageDependencyGraph.isScheduleableTask(event) && event.dur) {\n correctedEndTs = event.ts - 1;\n break;\n }\n\n children.push(event);\n }\n\n nodes.push(new CPUNode(evt, children, correctedEndTs));\n }\n\n return nodes;\n }\n\n static linkNetworkNodes(rootNode: NetworkNode, networkNodeOutput: NetworkNodeOutput): void {\n networkNodeOutput.nodes.forEach(node => {\n const directInitiatorRequest = node.request.initiatorRequest || rootNode.request;\n const directInitiatorNode = networkNodeOutput.idToNodeMap.get(directInitiatorRequest.requestId) || rootNode;\n const canDependOnInitiator = !directInitiatorNode.isDependentOn(node) && node.canDependOn(directInitiatorNode);\n const initiators = PageDependencyGraph.getNetworkInitiators(node.request);\n if (initiators.length) {\n initiators.forEach(initiator => {\n const parentCandidates = networkNodeOutput.urlToNodeMap.get(initiator) || [];\n // Only add the edge if the parent is unambiguous with valid timing and isn't circular.\n if (parentCandidates.length === 1 && parentCandidates[0].startTime <= node.startTime &&\n !parentCandidates[0].isDependentOn(node)) {\n node.addDependency(parentCandidates[0]);\n } else if (canDependOnInitiator) {\n directInitiatorNode.addDependent(node);\n }\n });\n } else if (canDependOnInitiator) {\n directInitiatorNode.addDependent(node);\n }\n\n // Make sure the nodes are attached to the graph if the initiator information was invalid.\n if (node !== rootNode && node.getDependencies().length === 0 && node.canDependOn(rootNode)) {\n node.addDependency(rootNode);\n }\n\n if (!node.request.redirects) {\n return;\n }\n\n const redirects = [...node.request.redirects, node.request];\n for (let i = 1; i < redirects.length; i++) {\n const redirectNode = networkNodeOutput.idToNodeMap.get(redirects[i - 1].requestId);\n const actualNode = networkNodeOutput.idToNodeMap.get(redirects[i].requestId);\n if (actualNode && redirectNode) {\n actualNode.addDependency(redirectNode);\n }\n }\n });\n }\n\n static linkCPUNodes(rootNode: Node, networkNodeOutput: NetworkNodeOutput, cpuNodes: CPUNode[]): void {\n const linkableResourceTypes = new Set<Lantern.ResourceType|undefined>([\n 'XHR',\n 'Fetch',\n 'Script',\n ]);\n\n function addDependentNetworkRequest(cpuNode: CPUNode, reqId: string): void {\n const networkNode = networkNodeOutput.idToNodeMap.get(reqId);\n if (!networkNode ||\n // Ignore all network nodes that started before this CPU task started\n // A network request that started earlier could not possibly have been started by this task\n networkNode.startTime <= cpuNode.startTime) {\n return;\n }\n const {request} = networkNode;\n const resourceType = request.resourceType || request.redirectDestination?.resourceType;\n if (!linkableResourceTypes.has(resourceType)) {\n // We only link some resources to CPU nodes because we observe LCP simulation\n // regressions when including images, etc.\n return;\n }\n cpuNode.addDependent(networkNode);\n }\n\n /**\n * If the node has an associated frameId, then create a dependency on the root document request\n * for the frame. The task obviously couldn't have started before the frame was even downloaded.\n */\n function addDependencyOnFrame(cpuNode: CPUNode, frameId: string|undefined): void {\n if (!frameId) {\n return;\n }\n const networkNode = networkNodeOutput.frameIdToNodeMap.get(frameId);\n if (!networkNode) {\n return;\n }\n // Ignore all network nodes that started after this CPU task started\n // A network request that started after could not possibly be required this task\n if (networkNode.startTime >= cpuNode.startTime) {\n return;\n }\n cpuNode.addDependency(networkNode);\n }\n\n function addDependencyOnUrl(cpuNode: CPUNode, url: string): void {\n if (!url) {\n return;\n }\n // Allow network requests that end up to 100ms before the task started\n // Some script evaluations can start before the script finishes downloading\n const minimumAllowableTimeSinceNetworkNodeEnd = -100 * 1000;\n const candidates = networkNodeOutput.urlToNodeMap.get(url) || [];\n\n let minCandidate = null;\n let minDistance = Infinity;\n // Find the closest request that finished before this CPU task started\n for (const candidate of candidates) {\n // Explicitly ignore all requests that started after this CPU node\n // A network request that started after this task started cannot possibly be a dependency\n if (cpuNode.startTime <= candidate.startTime) {\n return;\n }\n\n const distance = cpuNode.startTime - candidate.endTime;\n if (distance >= minimumAllowableTimeSinceNetworkNodeEnd && distance < minDistance) {\n minCandidate = candidate;\n minDistance = distance;\n }\n }\n\n if (!minCandidate) {\n return;\n }\n cpuNode.addDependency(minCandidate);\n }\n\n const timers = new Map<string, CPUNode>();\n for (const node of cpuNodes) {\n for (const evt of node.childEvents) {\n if (!evt.args.data) {\n continue;\n }\n\n const argsUrl = evt.args.data.url;\n const stackTraceUrls = (evt.args.data.stackTrace || []).map(l => l.url).filter(Boolean);\n\n switch (evt.name) {\n case 'TimerInstall':\n // @ts-expect-error - 'TimerInstall' event means timerId exists.\n timers.set(evt.args.data.timerId, node);\n stackTraceUrls.forEach(url => addDependencyOnUrl(node, url));\n break;\n case 'TimerFire': {\n // @ts-expect-error - 'TimerFire' event means timerId exists.\n const installer = timers.get(evt.args.data.timerId);\n if (!installer || installer.endTime > node.startTime) {\n break;\n }\n installer.addDependent(node);\n break;\n }\n\n case 'InvalidateLayout':\n case 'ScheduleStyleRecalculation':\n addDependencyOnFrame(node, evt.args.data.frame);\n stackTraceUrls.forEach(url => addDependencyOnUrl(node, url));\n break;\n\n case 'EvaluateScript':\n addDependencyOnFrame(node, evt.args.data.frame);\n // @ts-expect-error - 'EvaluateScript' event means argsUrl is defined.\n addDependencyOnUrl(node, argsUrl);\n stackTraceUrls.forEach(url => addDependencyOnUrl(node, url));\n break;\n\n case 'XHRReadyStateChange':\n // Only create the dependency if the request was completed\n // 'XHRReadyStateChange' event means readyState is defined.\n if (evt.args.data.readyState !== 4) {\n break;\n }\n\n // @ts-expect-error - 'XHRReadyStateChange' event means argsUrl is defined.\n addDependencyOnUrl(node, argsUrl);\n stackTraceUrls.forEach(url => addDependencyOnUrl(node, url));\n break;\n\n case 'FunctionCall':\n case 'v8.compile':\n addDependencyOnFrame(node, evt.args.data.frame);\n // @ts-expect-error - events mean argsUrl is defined.\n addDependencyOnUrl(node, argsUrl);\n break;\n\n case 'ParseAuthorStyleSheet':\n addDependencyOnFrame(node, evt.args.data.frame);\n // @ts-expect-error - 'ParseAuthorStyleSheet' event means styleSheetUrl is defined.\n addDependencyOnUrl(node, evt.args.data.styleSheetUrl);\n break;\n\n case 'ResourceSendRequest':\n addDependencyOnFrame(node, evt.args.data.frame);\n // @ts-expect-error - 'ResourceSendRequest' event means requestId is defined.\n addDependentNetworkRequest(node, evt.args.data.requestId);\n stackTraceUrls.forEach(url => addDependencyOnUrl(node, url));\n break;\n }\n }\n\n // Nodes starting before the root node cannot depend on it.\n if (node.getNumberOfDependencies() === 0 && node.canDependOn(rootNode)) {\n node.addDependency(rootNode);\n }\n }\n\n // Second pass to prune the graph of short tasks.\n const minimumEvtDur = SIGNIFICANT_DUR_THRESHOLD_MS * 1000;\n let foundFirstLayout = false;\n let foundFirstPaint = false;\n let foundFirstParse = false;\n\n for (const node of cpuNodes) {\n // Don't prune if event is the first ParseHTML/Layout/Paint.\n // See https://github.com/GoogleChrome/lighthouse/issues/9627#issuecomment-526699524 for more.\n let isFirst = false;\n if (!foundFirstLayout && node.childEvents.some(evt => evt.name === 'Layout')) {\n isFirst = foundFirstLayout = true;\n }\n if (!foundFirstPaint && node.childEvents.some(evt => evt.name === 'Paint')) {\n isFirst = foundFirstPaint = true;\n }\n if (!foundFirstParse && node.childEvents.some(evt => evt.name === 'ParseHTML')) {\n isFirst = foundFirstParse = true;\n }\n\n if (isFirst || node.duration >= minimumEvtDur) {\n // Don't prune this node. The task is long / important so it will impact simulation.\n continue;\n }\n\n // Prune the node if it isn't highly connected to minimize graph size. Rewiring the graph\n // here replaces O(M + N) edges with (M * N) edges, which is fine if either M or N is at\n // most 1.\n if (node.getNumberOfDependencies() === 1 || node.getNumberOfDependents() <= 1) {\n PageDependencyGraph.pruneNode(node);\n }\n }\n }\n\n /**\n * Removes the given node from the graph, but retains all paths between its dependencies and\n * dependents.\n */\n static pruneNode(node: Node): void {\n const dependencies = node.getDependencies();\n const dependents = node.getDependents();\n for (const dependency of dependencies) {\n node.removeDependency(dependency);\n for (const dependent of dependents) {\n dependency.addDependent(dependent);\n }\n }\n for (const dependent of dependents) {\n node.removeDependent(dependent);\n }\n }\n\n /**\n * TODO: remove when CDT backend in Lighthouse is gone. Until then, this is a useful debugging tool\n * to find delta between using CDP or the trace to create the network requests.\n *\n * When a test fails using the trace backend, I enabled this debug method and copied the network\n * requests when CDP was used, then when trace is used, and diff'd them. This method helped\n * remove non-logical differences from the comparison (order of properties, slight rounding\n * discrepancies, removing object cycles, etc).\n *\n * When using for a unit test, make sure to do `.only` so you are getting what you expect.\n */\n static debugNormalizeRequests(lanternRequests: Lantern.NetworkRequest[]): void {\n for (const request of lanternRequests) {\n request.rendererStartTime = Math.round(request.rendererStartTime * 1000) / 1000;\n request.networkRequestTime = Math.round(request.networkRequestTime * 1000) / 1000;\n request.responseHeadersEndTime = Math.round(request.responseHeadersEndTime * 1000) / 1000;\n request.networkEndTime = Math.round(request.networkEndTime * 1000) / 1000;\n }\n\n for (const r of lanternRequests) {\n delete r.rawRequest;\n if (r.initiatorRequest) {\n // @ts-expect-error\n r.initiatorRequest = {id: r.initiatorRequest.requestId};\n }\n if (r.redirectDestination) {\n // @ts-expect-error\n r.redirectDestination = {id: r.redirectDestination.requestId};\n }\n if (r.redirectSource) {\n // @ts-expect-error\n r.redirectSource = {id: r.redirectSource.requestId};\n }\n if (r.redirects) {\n // @ts-expect-error\n r.redirects = r.redirects.map(r2 => r2.requestId);\n }\n }\n const requests: Lantern.NetworkRequest[] = lanternRequests\n .map(r => ({\n requestId: r.requestId,\n connectionId: r.connectionId,\n connectionReused: r.connectionReused,\n url: r.url,\n protocol: r.protocol,\n parsedURL: r.parsedURL,\n documentURL: r.documentURL,\n rendererStartTime: r.rendererStartTime,\n networkRequestTime: r.networkRequestTime,\n responseHeadersEndTime: r.responseHeadersEndTime,\n networkEndTime: r.networkEndTime,\n transferSize: r.transferSize,\n resourceSize: r.resourceSize,\n fromDiskCache: r.fromDiskCache,\n fromMemoryCache: r.fromMemoryCache,\n finished: r.finished,\n statusCode: r.statusCode,\n redirectSource: r.redirectSource,\n redirectDestination: r.redirectDestination,\n redirects: r.redirects,\n failed: r.failed,\n initiator: r.initiator,\n timing: r.timing ? {\n requestTime: r.timing.requestTime,\n proxyStart: r.timing.proxyStart,\n proxyEnd: r.timing.proxyEnd,\n dnsStart: r.timing.dnsStart,\n dnsEnd: r.timing.dnsEnd,\n connectStart: r.timing.connectStart,\n connectEnd: r.timing.connectEnd,\n sslStart: r.timing.sslStart,\n sslEnd: r.timing.sslEnd,\n workerStart: r.timing.workerStart,\n workerReady: r.timing.workerReady,\n workerFetchStart: r.timing.workerFetchStart,\n workerRespondWithSettled: r.timing.workerRespondWithSettled,\n sendStart: r.timing.sendStart,\n sendEnd: r.timing.sendEnd,\n pushStart: r.timing.pushStart,\n pushEnd: r.timing.pushEnd,\n receiveHeadersStart: r.timing.receiveHeadersStart,\n receiveHeadersEnd: r.timing.receiveHeadersEnd,\n } :\n r.timing,\n resourceType: r.resourceType,\n mimeType: r.mimeType,\n priority: r.priority,\n initiatorRequest: r.initiatorRequest,\n frameId: r.frameId,\n fromWorker: r.fromWorker,\n isLinkPreload: r.isLinkPreload,\n serverResponseTime: r.serverResponseTime,\n }))\n .filter(r => !r.fromWorker);\n\n const debug = requests;\n // Set breakpoint here.\n // Copy `debug` and compare with https://www.diffchecker.com/text-compare/\n // eslint-disable-next-line no-console\n console.log(debug);\n }\n\n static createGraph(\n mainThreadEvents: Lantern.TraceEvent[], networkRequests: Lantern.NetworkRequest[],\n url: Lantern.Simulation.URL): Node {\n // This is for debugging trace/devtoolslog network records.\n // const debug = PageDependencyGraph.debugNormalizeRequests(networkRequests);\n const networkNodeOutput = PageDependencyGraph.getNetworkNodeOutput(networkRequests);\n const cpuNodes = PageDependencyGraph.getCPUNodes(mainThreadEvents);\n const {requestedUrl, mainDocumentUrl} = url;\n if (!requestedUrl) {\n throw new Core.LanternError('requestedUrl is required to get the root request');\n }\n if (!mainDocumentUrl) {\n throw new Core.LanternError('mainDocumentUrl is required to get the main resource');\n }\n\n const rootRequest = Core.NetworkAnalyzer.findResourceForUrl(networkRequests, requestedUrl);\n if (!rootRequest) {\n throw new Core.LanternError('rootRequest not found');\n }\n const rootNode = networkNodeOutput.idToNodeMap.get(rootRequest.requestId);\n if (!rootNode) {\n throw new Core.LanternError('rootNode not found');\n }\n const mainDocumentRequest = Core.NetworkAnalyzer.findLastDocumentForUrl(networkRequests, mainDocumentUrl);\n if (!mainDocumentRequest) {\n throw new Core.LanternError('mainDocumentRequest not found');\n }\n const mainDocumentNode = networkNodeOutput.idToNodeMap.get(mainDocumentRequest.requestId);\n if (!mainDocumentNode) {\n throw new Core.LanternError('mainDocumentNode not found');\n }\n\n PageDependencyGraph.linkNetworkNodes(rootNode, networkNodeOutput);\n PageDependencyGraph.linkCPUNodes(rootNode, networkNodeOutput, cpuNodes);\n mainDocumentNode.setIsMainDocument(true);\n\n if (NetworkNode.hasCycle(rootNode)) {\n throw new Core.LanternError('Invalid dependency graph created, cycle detected');\n }\n\n return rootNode;\n }\n\n // Unused, but useful for debugging.\n static printGraph(rootNode: Node, widthInCharacters = 100): void {\n function padRight(str: string, target: number, padChar = ' '): string {\n return str + padChar.repeat(Math.max(target - str.length, 0));\n }\n\n const nodes: Node[] = [];\n rootNode.traverse(node => nodes.push(node));\n nodes.sort((a, b) => a.startTime - b.startTime);\n\n const min = nodes[0].startTime;\n const max = nodes.reduce((max, node) => Math.max(max, node.endTime), 0);\n\n const totalTime = max - min;\n const timePerCharacter = totalTime / widthInCharacters;\n nodes.forEach(node => {\n const offset = Math.round((node.startTime - min) / timePerCharacter);\n const length = Math.ceil((node.endTime - node.startTime) / timePerCharacter);\n const bar = padRight('', offset) + padRight('', length, '=');\n\n // @ts-expect-error -- disambiguate displayName from across possible Node types.\n const displayName = node.request ? node.request.url : node.type;\n // eslint-disable-next-line\n console.log(padRight(bar, widthInCharacters), `| ${displayName.slice(0, 30)}`);\n });\n }\n}\n\nexport {PageDependencyGraph};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Metric.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/metrics/Metric.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAiC3C,MAAM,MAAM;IACV,MAAM,CAAC,aAAa,CAAC,eAA2B,EAAE,yBAAgE;QAEhH,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"Metric.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/metrics/Metric.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Core from '../core/core.js';\nimport * as Graph from '../graph/graph.js';\nimport type * as Simulation from '../simulation/simulation.js';\nimport type * as Types from '../types/types.js';\n\nexport interface MetricComputationDataInput {\n simulator: Simulation.Simulator;\n graph: Graph.Node<unknown>;\n processedNavigation: Types.Simulation.ProcessedNavigation;\n}\n\nexport interface MetricCoefficients {\n intercept: number;\n optimistic: number;\n pessimistic: number;\n}\n\nexport interface MetricResult<T = Types.AnyNetworkObject> {\n timing: number;\n timestamp?: never;\n optimisticEstimate: Simulation.Result<T>;\n pessimisticEstimate: Simulation.Result<T>;\n optimisticGraph: Graph.Node<T>;\n pessimisticGraph: Graph.Node;\n}\n\nexport interface Extras {\n optimistic: boolean;\n fcpResult?: MetricResult;\n lcpResult?: MetricResult;\n interactiveResult?: MetricResult;\n observedSpeedIndex?: number;\n}\n\nclass Metric {\n static getScriptUrls(dependencyGraph: Graph.Node, treatNodeAsRenderBlocking?: (node: Graph.NetworkNode) => boolean):\n Set<string> {\n const scriptUrls = new Set<string>();\n\n dependencyGraph.traverse(node => {\n if (node.type !== Graph.BaseNode.types.NETWORK) {\n return;\n }\n if (node.request.resourceType !== 'Script') {\n return;\n }\n if (treatNodeAsRenderBlocking?.(node)) {\n scriptUrls.add(node.request.url);\n }\n });\n\n return scriptUrls;\n }\n\n static get coefficients(): MetricCoefficients {\n throw new Core.LanternError('coefficients unimplemented!');\n }\n\n /* eslint-disable @typescript-eslint/no-unused-vars */\n\n /**\n * Returns the coefficients, scaled by the throttling settings if needed by the metric.\n * Some lantern metrics (speed-index) use components in their estimate that are not\n * from the simulator. In this case, we need to adjust the coefficients as the target throttling\n * settings change.\n */\n static getScaledCoefficients(rttMs: number): MetricCoefficients {\n return this.coefficients;\n }\n\n static getOptimisticGraph(dependencyGraph: Graph.Node, processedNavigation: Types.Simulation.ProcessedNavigation):\n Graph.Node {\n throw new Core.LanternError('Optimistic graph unimplemented!');\n }\n\n static getPessimisticGraph(dependencyGraph: Graph.Node, processedNavigation: Types.Simulation.ProcessedNavigation):\n Graph.Node {\n throw new Core.LanternError('Pessmistic graph unimplemented!');\n }\n\n static getEstimateFromSimulation(simulationResult: Simulation.Result, extras: Extras): Simulation.Result {\n return simulationResult;\n }\n\n /* eslint-enable @typescript-eslint/no-unused-vars */\n\n static compute(data: MetricComputationDataInput, extras?: Omit<Extras, 'optimistic'>): MetricResult {\n const {simulator, graph, processedNavigation} = data;\n\n const metricName = this.name.replace('Lantern', '');\n const optimisticGraph = this.getOptimisticGraph(graph, processedNavigation);\n const pessimisticGraph = this.getPessimisticGraph(graph, processedNavigation);\n\n let simulateOptions = {label: `optimistic${metricName}`};\n const optimisticSimulation = simulator.simulate(optimisticGraph, simulateOptions);\n\n simulateOptions = {label: `pessimistic${metricName}`};\n const pessimisticSimulation = simulator.simulate(pessimisticGraph, simulateOptions);\n\n const optimisticEstimate = this.getEstimateFromSimulation(\n optimisticSimulation,\n {...extras, optimistic: true},\n );\n\n const pessimisticEstimate = this.getEstimateFromSimulation(\n pessimisticSimulation,\n {...extras, optimistic: false},\n );\n\n const coefficients = this.getScaledCoefficients(simulator.rtt);\n // Estimates under 1s don't really follow the normal curve fit, minimize the impact of the intercept\n const interceptMultiplier = coefficients.intercept > 0 ? Math.min(1, optimisticEstimate.timeInMs / 1000) : 1;\n const timing = coefficients.intercept * interceptMultiplier +\n coefficients.optimistic * optimisticEstimate.timeInMs + coefficients.pessimistic * pessimisticEstimate.timeInMs;\n\n return {\n timing,\n optimisticEstimate,\n pessimisticEstimate,\n optimisticGraph,\n pessimisticGraph,\n };\n }\n}\n\nexport {Metric};\n"]}
|
|
@@ -7,10 +7,10 @@ declare class TotalBlockingTime extends Metric {
|
|
|
7
7
|
static getPessimisticGraph(dependencyGraph: Graph.Node): Graph.Node;
|
|
8
8
|
static getEstimateFromSimulation(simulation: Simulation.Result, extras: Extras): Simulation.Result;
|
|
9
9
|
static compute(data: MetricComputationDataInput, extras?: Omit<Extras, 'optimistic'>): MetricResult;
|
|
10
|
-
static getTopLevelEvents(nodeTimings: Simulation.Result['nodeTimings'], minDurationMs: number): {
|
|
10
|
+
static getTopLevelEvents(nodeTimings: Simulation.Result['nodeTimings'], minDurationMs: number): Array<{
|
|
11
11
|
start: number;
|
|
12
12
|
end: number;
|
|
13
13
|
duration: number;
|
|
14
|
-
}
|
|
14
|
+
}>;
|
|
15
15
|
}
|
|
16
16
|
export { TotalBlockingTime };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TotalBlockingTime.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/metrics/TotalBlockingTime.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EAEL,MAAM,GAIP,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,uBAAuB,EAAE,0BAA0B,EAAC,MAAM,eAAe,CAAC;AAElF,MAAM,iBAAkB,SAAQ,MAAM;IACpC,MAAM,KAAc,YAAY;QAC9B,OAAO;YACL,SAAS,EAAE,CAAC;YACZ,UAAU,EAAE,GAAG;YACf,WAAW,EAAE,GAAG;SACjB,CAAC;IACJ,CAAC;IAED,MAAM,CAAU,kBAAkB,CAAC,eAA2B;QAC5D,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,MAAM,CAAU,mBAAmB,CAAC,eAA2B;QAC7D,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,MAAM,CAAU,yBAAyB,CAAC,UAA6B,EAAE,MAAc;QACrF,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACtB,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;YAC9B,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,2BAA2B,CAAC,CAAC;QAC3D,CAAC;QAED,4FAA4F;QAC5F,+FAA+F;QAC/F,6FAA6F;QAC7F,aAAa;QACb,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YAC/C,MAAM,CAAC,SAAS,CAAC,kBAAkB,CAAC,QAAQ,CAAC;QAErF,6FAA6F;QAC7F,gGAAgG;QAChG,gGAAgG;QAChG,qBAAqB;QACrB,MAAM,iBAAiB,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YACtD,MAAM,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,QAAQ,CAAC;QAEpG,MAAM,aAAa,GAAG,uBAAuB,CAAC;QAE9C,MAAM,MAAM,GAAG,iBAAiB,CAAC,iBAAiB,CAC9C,UAAU,CAAC,WAAW,EACtB,aAAa,CAChB,CAAC;QAEF,OAAO;YACL,QAAQ,EAAE,0BAA0B,CAChC,MAAM,EACN,WAAW,EACX,iBAAiB,CAChB;YACL,WAAW,EAAE,UAAU,CAAC,WAAW;SACpC,CAAC;IACJ,CAAC;IAED,MAAM,CAAU,OAAO,CAAC,IAAgC,EAAE,MAAmC;QAC3F,MAAM,SAAS,GAAG,MAAM,EAAE,SAAS,CAAC;QACpC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,6CAA6C,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,iBAAiB,GAAG,MAAM,EAAE,SAAS,CAAC;QAC5C,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,qDAAqD,CAAC,CAAC;QACrF,CAAC;QAED,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,CAAC,iBAAiB,CAAC,WAA6C,EAAE,aAAqB;QAE3F,MAAM,MAAM,GAA0D,EAAE,CAAC;QAEzE,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;YACnD,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;gBAC3C,SAAS;YACX,CAAC;YACD,+CAA+C;YAC/C,IAAI,MAAM,CAAC,QAAQ,GAAG,aAAa,EAAE,CAAC;gBACpC,SAAS;YACX,CAAC;YAED,MAAM,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,MAAM,CAAC,SAAS;gBACvB,GAAG,EAAE,MAAM,CAAC,OAAO;gBACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;aAC1B,CAAC,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAED,OAAO,EAAC,iBAAiB,EAAC,CAAC","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Core from '../core/core.js';\nimport * as Graph from '../graph/graph.js';\nimport type * as Simulation from '../simulation/simulation.js';\n\nimport {\n type Extras,\n Metric,\n type MetricCoefficients,\n type MetricComputationDataInput,\n type MetricResult,\n} from './Metric.js';\nimport {BLOCKING_TIME_THRESHOLD, calculateSumOfBlockingTime} from './TBTUtils.js';\n\nclass TotalBlockingTime extends Metric {\n static override get coefficients(): MetricCoefficients {\n return {\n intercept: 0,\n optimistic: 0.5,\n pessimistic: 0.5,\n };\n }\n\n static override getOptimisticGraph(dependencyGraph: Graph.Node): Graph.Node {\n return dependencyGraph;\n }\n\n static override getPessimisticGraph(dependencyGraph: Graph.Node): Graph.Node {\n return dependencyGraph;\n }\n\n static override getEstimateFromSimulation(simulation: Simulation.Result, extras: Extras): Simulation.Result {\n if (!extras.fcpResult) {\n throw new Core.LanternError('missing fcpResult');\n }\n if (!extras.interactiveResult) {\n throw new Core.LanternError('missing interactiveResult');\n }\n\n // Intentionally use the opposite FCP estimate. A pessimistic FCP is higher than equal to an\n // optimistic FCP, which means potentially more tasks are excluded from the Total Blocking Time\n // computation. So a more pessimistic FCP gives a more optimistic Total Blocking Time for the\n // same work.\n const fcpTimeInMs = extras.optimistic ? extras.fcpResult.pessimisticEstimate.timeInMs :\n extras.fcpResult.optimisticEstimate.timeInMs;\n\n // Similarly, we always have pessimistic TTI >= optimistic TTI. Therefore, picking optimistic\n // TTI means our window of interest is smaller and thus potentially more tasks are excluded from\n // Total Blocking Time computation, yielding a lower (more optimistic) Total Blocking Time value\n // for the same work.\n const interactiveTimeMs = extras.optimistic ? extras.interactiveResult.optimisticEstimate.timeInMs :\n extras.interactiveResult.pessimisticEstimate.timeInMs;\n\n const minDurationMs = BLOCKING_TIME_THRESHOLD;\n\n const events = TotalBlockingTime.getTopLevelEvents(\n simulation.nodeTimings,\n minDurationMs,\n );\n\n return {\n timeInMs: calculateSumOfBlockingTime(\n events,\n fcpTimeInMs,\n interactiveTimeMs,\n ),\n nodeTimings: simulation.nodeTimings,\n };\n }\n\n static override compute(data: MetricComputationDataInput, extras?: Omit<Extras, 'optimistic'>): MetricResult {\n const fcpResult = extras?.fcpResult;\n if (!fcpResult) {\n throw new Core.LanternError('FCP is required to calculate the TBT metric');\n }\n\n const interactiveResult = extras?.fcpResult;\n if (!interactiveResult) {\n throw new Core.LanternError('Interactive is required to calculate the TBT metric');\n }\n\n return super.compute(data, extras);\n }\n\n static getTopLevelEvents(nodeTimings: Simulation.Result['nodeTimings'], minDurationMs: number):\n {start: number, end: number, duration: number}
|
|
1
|
+
{"version":3,"file":"TotalBlockingTime.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/metrics/TotalBlockingTime.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Core from '../core/core.js';\nimport * as Graph from '../graph/graph.js';\nimport type * as Simulation from '../simulation/simulation.js';\n\nimport {\n type Extras,\n Metric,\n type MetricCoefficients,\n type MetricComputationDataInput,\n type MetricResult,\n} from './Metric.js';\nimport {BLOCKING_TIME_THRESHOLD, calculateSumOfBlockingTime} from './TBTUtils.js';\n\nclass TotalBlockingTime extends Metric {\n static override get coefficients(): MetricCoefficients {\n return {\n intercept: 0,\n optimistic: 0.5,\n pessimistic: 0.5,\n };\n }\n\n static override getOptimisticGraph(dependencyGraph: Graph.Node): Graph.Node {\n return dependencyGraph;\n }\n\n static override getPessimisticGraph(dependencyGraph: Graph.Node): Graph.Node {\n return dependencyGraph;\n }\n\n static override getEstimateFromSimulation(simulation: Simulation.Result, extras: Extras): Simulation.Result {\n if (!extras.fcpResult) {\n throw new Core.LanternError('missing fcpResult');\n }\n if (!extras.interactiveResult) {\n throw new Core.LanternError('missing interactiveResult');\n }\n\n // Intentionally use the opposite FCP estimate. A pessimistic FCP is higher than equal to an\n // optimistic FCP, which means potentially more tasks are excluded from the Total Blocking Time\n // computation. So a more pessimistic FCP gives a more optimistic Total Blocking Time for the\n // same work.\n const fcpTimeInMs = extras.optimistic ? extras.fcpResult.pessimisticEstimate.timeInMs :\n extras.fcpResult.optimisticEstimate.timeInMs;\n\n // Similarly, we always have pessimistic TTI >= optimistic TTI. Therefore, picking optimistic\n // TTI means our window of interest is smaller and thus potentially more tasks are excluded from\n // Total Blocking Time computation, yielding a lower (more optimistic) Total Blocking Time value\n // for the same work.\n const interactiveTimeMs = extras.optimistic ? extras.interactiveResult.optimisticEstimate.timeInMs :\n extras.interactiveResult.pessimisticEstimate.timeInMs;\n\n const minDurationMs = BLOCKING_TIME_THRESHOLD;\n\n const events = TotalBlockingTime.getTopLevelEvents(\n simulation.nodeTimings,\n minDurationMs,\n );\n\n return {\n timeInMs: calculateSumOfBlockingTime(\n events,\n fcpTimeInMs,\n interactiveTimeMs,\n ),\n nodeTimings: simulation.nodeTimings,\n };\n }\n\n static override compute(data: MetricComputationDataInput, extras?: Omit<Extras, 'optimistic'>): MetricResult {\n const fcpResult = extras?.fcpResult;\n if (!fcpResult) {\n throw new Core.LanternError('FCP is required to calculate the TBT metric');\n }\n\n const interactiveResult = extras?.fcpResult;\n if (!interactiveResult) {\n throw new Core.LanternError('Interactive is required to calculate the TBT metric');\n }\n\n return super.compute(data, extras);\n }\n\n static getTopLevelEvents(nodeTimings: Simulation.Result['nodeTimings'], minDurationMs: number):\n Array<{start: number, end: number, duration: number}> {\n const events: Array<{start: number, end: number, duration: number}> = [];\n\n for (const [node, timing] of nodeTimings.entries()) {\n if (node.type !== Graph.BaseNode.types.CPU) {\n continue;\n }\n // Filtering out events below minimum duration.\n if (timing.duration < minDurationMs) {\n continue;\n }\n\n events.push({\n start: timing.startTime,\n end: timing.endTime,\n duration: timing.duration,\n });\n }\n\n return events;\n }\n}\n\nexport {TotalBlockingTime};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Lantern.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/types/Lantern.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAI7B,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,GAAG,EAAE,KAAK;IACV,KAAK,EAAE,OAAO;IACd,WAAW,EAAE,aAAa;IAC1B,MAAM,EAAE,QAAQ;IAChB,UAAU,EAAE,YAAY;IACxB,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,UAAU;IACpB,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,WAAW;IACtB,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;IACpB,cAAc,EAAE,gBAAgB;IAChC,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,WAAW;IACtB,kBAAkB,EAAE,oBAAoB;IACxC,QAAQ,EAAE,UAAU;CACZ,CAAC","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport type * as Protocol from '../../../../generated/protocol.js';\n\nexport const NetworkRequestTypes = {\n XHR: 'XHR',\n Fetch: 'Fetch',\n EventSource: 'EventSource',\n Script: 'Script',\n Stylesheet: 'Stylesheet',\n Image: 'Image',\n Media: 'Media',\n Font: 'Font',\n Document: 'Document',\n TextTrack: 'TextTrack',\n WebSocket: 'WebSocket',\n Other: 'Other',\n Manifest: 'Manifest',\n SignedExchange: 'SignedExchange',\n Ping: 'Ping',\n Preflight: 'Preflight',\n CSPViolationReport: 'CSPViolationReport',\n Prefetch: 'Prefetch',\n} as const;\n\nexport interface TraceEvent {\n name: string;\n args: {\n name?: string,\n data?: {\n frame?: string,\n readyState?: number,\n stackTrace?: {\n
|
|
1
|
+
{"version":3,"file":"Lantern.js","sourceRoot":"","sources":["../../../../../../../../front_end/models/trace/lantern/types/Lantern.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAI7B,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,GAAG,EAAE,KAAK;IACV,KAAK,EAAE,OAAO;IACd,WAAW,EAAE,aAAa;IAC1B,MAAM,EAAE,QAAQ;IAChB,UAAU,EAAE,YAAY;IACxB,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,UAAU;IACpB,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,WAAW;IACtB,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;IACpB,cAAc,EAAE,gBAAgB;IAChC,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,WAAW;IACtB,kBAAkB,EAAE,oBAAoB;IACxC,QAAQ,EAAE,UAAU;CACZ,CAAC","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport type * as Protocol from '../../../../generated/protocol.js';\n\nexport const NetworkRequestTypes = {\n XHR: 'XHR',\n Fetch: 'Fetch',\n EventSource: 'EventSource',\n Script: 'Script',\n Stylesheet: 'Stylesheet',\n Image: 'Image',\n Media: 'Media',\n Font: 'Font',\n Document: 'Document',\n TextTrack: 'TextTrack',\n WebSocket: 'WebSocket',\n Other: 'Other',\n Manifest: 'Manifest',\n SignedExchange: 'SignedExchange',\n Ping: 'Ping',\n Preflight: 'Preflight',\n CSPViolationReport: 'CSPViolationReport',\n Prefetch: 'Prefetch',\n} as const;\n\nexport interface TraceEvent {\n name: string;\n args: {\n name?: string,\n data?: {\n frame?: string,\n readyState?: number,\n stackTrace?: Array<{\n url: string,\n }>,\n url?: string,\n },\n };\n pid: number;\n tid: number;\n /** Timestamp of the event in microseconds. */\n ts: number;\n dur: number;\n}\nexport interface Trace {\n traceEvents: TraceEvent[];\n}\nexport type ResourcePriority = ('VeryLow'|'Low'|'Medium'|'High'|'VeryHigh');\nexport type ResourceType = keyof typeof NetworkRequestTypes;\ntype InitiatorType = ('parser'|'script'|'preload'|'SignedExchange'|'preflight'|'other');\nexport type ResourceTiming = Protocol.Network.ResourceTiming;\nexport interface CallStack {\n callFrames: Array<{\n scriptId: string,\n url: string,\n lineNumber: number,\n columnNumber: number,\n functionName: string,\n }>;\n parent?: CallStack;\n}\n\nexport interface ParsedURL {\n /**\n * Equivalent to a `new URL(url).protocol` BUT w/o the trailing colon (:)\n */\n scheme: string;\n /**\n * Equivalent to a `new URL(url).hostname`\n */\n host: string;\n securityOrigin: string;\n}\n\n// When Lantern NetworkRequests are constructed, the source-of-truth of the network record is given as `rawRequest`.\n// Internally Lantern doesn't care about the type of this field, so a default type is given to simplify internal code\n// by avoiding unnecessary typescript overhead.\n// If callers want to access the underlying network record, they are expected to make use of this generic on top-level\n// interfaces like Simulator.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyNetworkObject = any;\n\nexport interface NetworkRequest<T = AnyNetworkObject> {\n requestId: string;\n connectionId: number;\n connectionReused: boolean;\n url: string;\n protocol: string;\n parsedURL: ParsedURL;\n documentURL: string;\n /** When the renderer process initially discovers a network request, in milliseconds. */\n rendererStartTime: number;\n /**\n * When the network service is about to handle a request, ie. just before going to the\n * HTTP cache or going to the network for DNS/connection setup, in milliseconds.\n */\n networkRequestTime: number;\n /**\n * When the last byte of the response headers is received, in milliseconds.\n * Equal to networkRequestTime if no data is received over the\n * network (ex: cached requests or data urls).\n */\n responseHeadersEndTime: number;\n /** When the last byte of the response body is received, in milliseconds. */\n networkEndTime: number;\n transferSize: number;\n resourceSize: number;\n fromDiskCache: boolean;\n fromMemoryCache: boolean;\n isLinkPreload: boolean;\n finished: boolean;\n failed: boolean;\n statusCode: number;\n /** The network request that redirected to this one */\n redirectSource: NetworkRequest<T>|undefined;\n /** The network request that this one redirected to */\n redirectDestination: NetworkRequest<T>|undefined;\n // TODO: can't use Protocol.Network.Initiator because of type mismatch in Lighthouse initiator.\n initiator: {\n type: InitiatorType,\n url?: string,\n stack?: CallStack,\n };\n initiatorRequest: NetworkRequest<T>|undefined;\n /** The chain of network requests that redirected to this one */\n redirects: NetworkRequest[]|undefined;\n timing: Protocol.Network.ResourceTiming|undefined;\n resourceType: ResourceType|undefined;\n mimeType: string;\n priority: ResourcePriority;\n frameId: string|undefined;\n fromWorker: boolean;\n /**\n * Optional value for how long the server took to respond to this request.\n * When not provided, the server response time is derived from the timing object.\n */\n serverResponseTime?: number;\n /**\n * Implementation-specific canonical data structure that this Lantern NetworkRequest\n * was derived from.\n * Users of Lantern create a NetworkRequest matching this interface,\n * but can store the source-of-truth for their network model in this property.\n * This is then accessible as a read-only property on NetworkNode.\n */\n rawRequest?: T;\n}\n\nexport namespace Simulation {\n export interface URL {\n /** URL of the initially requested URL */\n requestedUrl?: string;\n /** URL of the last document request */\n mainDocumentUrl?: string;\n }\n\n /** Simulation settings that control the amount of network & cpu throttling in the run. */\n export interface ThrottlingSettings {\n /** The round trip time in milliseconds. */\n rttMs?: number;\n /** The network throughput in kilobits per second. */\n throughputKbps?: number;\n // devtools settings\n /** The network request latency in milliseconds. */\n requestLatencyMs?: number;\n /** The network download throughput in kilobits per second. */\n downloadThroughputKbps?: number;\n /** The network upload throughput in kilobits per second. */\n uploadThroughputKbps?: number;\n // used by both\n /** The amount of slowdown applied to the cpu (1/<cpuSlowdownMultiplier>). */\n cpuSlowdownMultiplier?: number;\n }\n\n export interface PrecomputedLanternData {\n additionalRttByOrigin: {[origin: string]: number};\n serverResponseTimeByOrigin: {[origin: string]: number};\n }\n\n export interface Settings {\n networkAnalysis: {\n rtt: number,\n additionalRttByOrigin: Map<string, number>,\n serverResponseTimeByOrigin: Map<string, number>,\n throughput: number,\n };\n /** The method used to throttle the network. */\n throttlingMethod: 'devtools'|'simulate'|'provided';\n /** The throttling config settings. */\n throttling?: Required<ThrottlingSettings>;\n /** Precomputed lantern estimates to use instead of observed analysis. */\n precomputedLanternData?: PrecomputedLanternData|null;\n }\n\n export interface Options {\n rtt?: number;\n throughput?: number;\n observedThroughput: number;\n maximumConcurrentRequests?: number;\n cpuSlowdownMultiplier?: number;\n layoutTaskMultiplier?: number;\n additionalRttByOrigin?: Map<string, number>;\n serverResponseTimeByOrigin?: Map<string, number>;\n }\n\n export interface ProcessedNavigation {\n timestamps: {\n firstContentfulPaint: number,\n largestContentfulPaint?: number,\n };\n }\n\n export interface NodeTiming {\n startTime: number;\n endTime: number;\n duration: number;\n }\n}\n"]}
|
|
@@ -45,6 +45,9 @@
|
|
|
45
45
|
{
|
|
46
46
|
"path": "../../core/platform/bundle-tsconfig.json"
|
|
47
47
|
},
|
|
48
|
+
{
|
|
49
|
+
"path": "../../core/root/bundle-tsconfig.json"
|
|
50
|
+
},
|
|
48
51
|
{
|
|
49
52
|
"path": "../../core/sdk/bundle-tsconfig.json"
|
|
50
53
|
},
|
|
@@ -69,9 +72,6 @@
|
|
|
69
72
|
{
|
|
70
73
|
"path": "lantern/bundle-tsconfig.json"
|
|
71
74
|
},
|
|
72
|
-
{
|
|
73
|
-
"path": "root-causes/bundle-tsconfig.json"
|
|
74
|
-
},
|
|
75
75
|
{
|
|
76
76
|
"path": "types/bundle-tsconfig.json"
|
|
77
77
|
}
|
package/models/trace/trace.d.ts
CHANGED
|
@@ -6,7 +6,6 @@ import * as Lantern from './lantern/lantern.js';
|
|
|
6
6
|
import * as LanternComputationData from './LanternComputationData.js';
|
|
7
7
|
import * as TraceModel from './ModelImpl.js';
|
|
8
8
|
import * as Processor from './Processor.js';
|
|
9
|
-
import * as RootCauses from './root-causes/root-causes.js';
|
|
10
9
|
import * as TracingManager from './TracingManager.js';
|
|
11
10
|
import * as Types from './types/types.js';
|
|
12
|
-
export { Extras, Handlers, Helpers, Insights, Lantern, LanternComputationData, Processor,
|
|
11
|
+
export { Extras, Handlers, Helpers, Insights, Lantern, LanternComputationData, Processor, TraceModel, TracingManager, Types, };
|
package/models/trace/trace.js
CHANGED
|
@@ -9,8 +9,7 @@ import * as Lantern from './lantern/lantern.js';
|
|
|
9
9
|
import * as LanternComputationData from './LanternComputationData.js';
|
|
10
10
|
import * as TraceModel from './ModelImpl.js';
|
|
11
11
|
import * as Processor from './Processor.js';
|
|
12
|
-
import * as RootCauses from './root-causes/root-causes.js';
|
|
13
12
|
import * as TracingManager from './TracingManager.js';
|
|
14
13
|
import * as Types from './types/types.js';
|
|
15
|
-
export { Extras, Handlers, Helpers, Insights, Lantern, LanternComputationData, Processor,
|
|
14
|
+
export { Extras, Handlers, Helpers, Insights, Lantern, LanternComputationData, Processor, TraceModel, TracingManager, Types, };
|
|
16
15
|
//# sourceMappingURL=trace.js.map
|