UNPKG

lighthouse

Version:

Automated auditing, performance metrics, and best practices for the web.

162 lines 7.36 kB
export type TaskGroup = import("./task-groups.js").TaskGroup; export type TaskNode = { event: LH.TraceEvent; endEvent: LH.TraceEvent | undefined; children: TaskNode[]; parent: TaskNode | undefined; /** * Indicates that the task had an endTime that was inferred rather than specified in the trace. i.e. in the source trace this task was unbounded. */ unbounded: boolean; startTime: number; endTime: number; duration: number; selfTime: number; attributableURLs: string[]; group: TaskGroup; }; export type PriorTaskData = { timers: Map<string, TaskNode>; xhrs: Map<string, TaskNode>; frameURLsById: Map<string, string>; lastTaskURLs: string[]; }; /** * @fileoverview * * This artifact converts the array of raw trace events into an array of hierarchical * tasks for easier consumption and bottom-up analysis. * * Events are easily produced but difficult to consume. They're a mixture of start/end markers, "complete" events, etc. * @see https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview * * LH's TaskNode is an artifact that fills in the gaps a trace event leaves behind. * i.e. when did it end? which events are children/parents of this one? * * Each task will have its group/classification, start time, end time, * duration, and self time computed. Each task will potentially have a parent, children, and an * attributableURL for the script that was executing/forced this execution. */ /** @typedef {import('./task-groups.js').TaskGroup} TaskGroup */ /** * @typedef TaskNode * @prop {LH.TraceEvent} event * @prop {LH.TraceEvent|undefined} endEvent * @prop {TaskNode[]} children * @prop {TaskNode|undefined} parent * @prop {boolean} unbounded Indicates that the task had an endTime that was inferred rather than specified in the trace. i.e. in the source trace this task was unbounded. * @prop {number} startTime * @prop {number} endTime * @prop {number} duration * @prop {number} selfTime * @prop {string[]} attributableURLs * @prop {TaskGroup} group */ /** @typedef {{timers: Map<string, TaskNode>, xhrs: Map<string, TaskNode>, frameURLsById: Map<string, string>, lastTaskURLs: string[]}} PriorTaskData */ export class MainThreadTasks { /** * @param {LH.TraceEvent} event * @param {LH.TraceEvent} [endEvent] * @return {TaskNode} */ static _createNewTaskNode(event: LH.TraceEvent, endEvent?: LH.TraceEvent): TaskNode; /** * * @param {TaskNode} currentTask * @param {number} stopTs * @param {PriorTaskData} priorTaskData * @param {Array<LH.TraceEvent>} reverseEventsQueue */ static _assignAllTimersUntilTs(currentTask: TaskNode, stopTs: number, priorTaskData: PriorTaskData, reverseEventsQueue: Array<LH.TraceEvent>): void; /** * This function takes the start and end events from a thread and creates tasks from them. * We do this by iterating through the start and end event arrays simultaneously. For each start * event we attempt to find its end event. * * Because of this matching of start/end events and the need to be mutating our end events queue, * we reverse the array to more efficiently `.pop()` them off rather than `.shift()` them off. * While it's true the worst case runtime here is O(n^2), ~99.999% of the time the reverse loop is O(1) * because the overwhelmingly common case is that end event for a given start event is simply the very next event in our queue. * * @param {LH.TraceEvent[]} taskStartEvents * @param {LH.TraceEvent[]} taskEndEvents * @param {number} traceEndTs * @return {TaskNode[]} */ static _createTasksFromStartAndEndEvents(taskStartEvents: LH.TraceEvent[], taskEndEvents: LH.TraceEvent[], traceEndTs: number): TaskNode[]; /** * This function iterates through the tasks to set the `.parent`/`.children` properties of tasks * according to their implied nesting structure. If any of these relationships seem impossible based on * the timestamps, this method will throw. * * @param {TaskNode[]} sortedTasks * @param {LH.TraceEvent[]} timerInstallEvents * @param {PriorTaskData} priorTaskData */ static _createTaskRelationships(sortedTasks: TaskNode[], timerInstallEvents: LH.TraceEvent[], priorTaskData: PriorTaskData): void; /** * This function takes the raw trace events sorted in increasing timestamp order and outputs connected task nodes. * To create the task heirarchy we make several passes over the events. * * 1. Create three arrays of X/B events, E events, and TimerInstall events. * 2. Create tasks for each X/B event, throwing if a matching E event cannot be found for a given B. * 3. Sort the tasks by ↑ startTime, ↓ duration. * 4. Match each task to its parent, throwing if there is any invalid overlap between tasks. * 5. Sort the tasks once more by ↑ startTime, ↓ duration in case they changed during relationship creation. * * @param {LH.TraceEvent[]} mainThreadEvents * @param {PriorTaskData} priorTaskData * @param {number} traceEndTs * @return {TaskNode[]} */ static _createTasksFromEvents(mainThreadEvents: LH.TraceEvent[], priorTaskData: PriorTaskData, traceEndTs: number): TaskNode[]; /** * @param {TaskNode} task * @param {TaskNode|undefined} parent * @return {number} */ static _computeRecursiveSelfTime(task: TaskNode, parent: TaskNode | undefined): number; /** * @param {TaskNode} task * @param {string[]} parentURLs * @param {string[]} allURLsInTree * @param {PriorTaskData} priorTaskData */ static _computeRecursiveAttributableURLs(task: TaskNode, parentURLs: string[], allURLsInTree: string[], priorTaskData: PriorTaskData): void; /** * @param {TaskNode} task * @param {Array<string>} urls */ static _setRecursiveEmptyAttributableURLs(task: TaskNode, urls: Array<string>): void; /** * @param {TaskNode} task * @param {TaskGroup} [parentGroup] */ static _computeRecursiveTaskGroup(task: TaskNode, parentGroup?: TaskGroup): void; /** * @param {LH.TraceEvent[]} mainThreadEvents * @param {Array<{id: string, url: string}>} frames * @param {number} traceEndTs * @param {number} [traceStartTs] Optional time-0 ts for tasks. Tasks before this point will have negative start/end times. Defaults to the first task found. * @return {TaskNode[]} */ static getMainThreadTasks(mainThreadEvents: LH.TraceEvent[], frames: Array<{ id: string; url: string; }>, traceEndTs: number, traceStartTs?: number): TaskNode[]; /** * Prints an artistic rendering of the task tree for easier debugability. * * @param {TaskNode[]} tasks * @param {{printWidth?: number, startTime?: number, endTime?: number, taskLabelFn?: (node: TaskNode) => string}} options * @return {string} */ static printTaskTreeToDebugString(tasks: TaskNode[], options?: { printWidth?: number; startTime?: number; endTime?: number; taskLabelFn?: (node: TaskNode) => string; }): string; } import * as LH from '../../../types/lh.js'; //# sourceMappingURL=main-thread-tasks.d.ts.map