A fast, interactive web-based viewer for performance profiles with support for multiple profiler formats
—
Core data structures for representing performance profiles, call trees, and frame information with weight calculations and hierarchical relationships.
Core classes for representing performance profiling data.
/**
* Main profile class representing a complete performance profile
* Contains timing data, call trees, and metadata
*/
class Profile {
/** Get the human-readable name of this profile */
getName(): string;
/** Set the name of this profile */
setName(name: string): void;
/** Get the unit of measurement for weights (e.g., 'milliseconds', 'bytes') */
getWeightUnit(): string;
/** Get the total weight/duration of this profile */
getTotalWeight(): number;
/** Get the formatter for displaying weight values */
getValueFormatter(): ValueFormatter;
/** Get the number of samples in this profile */
getSampleCount(): number;
/** Check if this profile has timing information */
getHasTiming(): boolean;
/** Get the minimum timestamp in the profile */
getMinValue(): number;
/** Get the maximum timestamp in the profile */
getMaxValue(): number;
}
/**
* Collection of related profiles, typically from the same profiling session
*/
interface ProfileGroup {
/** Human-readable name for this group of profiles */
name: string;
/** Index of the profile to display by default */
indexToView: number;
/** Array of profiles in this group */
profiles: Profile[];
}Classes and interfaces for representing individual stack frames.
/**
* Metadata for a stack frame
*/
interface FrameInfo {
/** Unique identifier for this frame */
key: string | number;
/** Display name of the frame (e.g., function name) */
name: string;
/** Source file path (optional) */
file?: string;
/** Line number in source file (1-based, optional) */
line?: number;
/** Column number in source file (1-based, optional) */
col?: number;
}
/**
* Stack frame with timing and weight information
* Extends HasWeights to track self and total time/memory usage
*/
class Frame extends HasWeights {
/** Unique identifier for this frame */
key: string | number;
/** Display name of the frame */
name: string;
/** Source file path (optional) */
file?: string;
/** Line number in source file (optional) */
line?: number;
/** Column number in source file (optional) */
col?: number;
/**
* Create a new frame from frame info
* @param frameInfo - Metadata for the frame
*/
constructor(frameInfo: FrameInfo);
}
/**
* Base class providing weight tracking functionality
* Used by Frame and CallTreeNode to track timing/memory data
*/
class HasWeights {
/** Get the self weight (time spent directly in this frame) */
getSelfWeight(): number;
/** Get the total weight (time spent in this frame and all children) */
getTotalWeight(): number;
/** Add to the total weight */
addToTotalWeight(delta: number): void;
/** Add to the self weight */
addToSelfWeight(delta: number): void;
/** Copy weights from another HasWeights instance */
overwriteWeightWith(other: HasWeights): void;
}Classes for representing hierarchical call relationships.
/**
* Node in a call tree representing a function call with timing data
* Each node tracks its frame, parent, children, and weight information
*/
class CallTreeNode extends HasWeights {
/** The frame this node represents */
frame: Frame;
/** Parent node in the call tree (null for root) */
parent: CallTreeNode | null;
/** Child nodes representing functions called from this frame */
children: CallTreeNode[];
/**
* Create a new call tree node
* @param frame - The frame this node represents
* @param parent - Parent node (null for root)
*/
constructor(frame: Frame, parent: CallTreeNode | null);
/** Check if this is a root node (has no parent) */
isRoot(): boolean;
/** Get or create a child node for the given frame */
getOrInsertChildWithFrame(frame: Frame): CallTreeNode;
}Builder classes for constructing profiles from raw profiling data.
/**
* Builder for call tree based profiles (hierarchical timing data)
* Used for profiles that track function call relationships over time
*/
class CallTreeProfileBuilder {
/**
* Create a new call tree profile builder
* @param valueFormatter - Formatter for displaying timing values
*/
constructor(valueFormatter?: ValueFormatter);
/** Get the root node of the call tree */
getRoot(): CallTreeNode;
/**
* Enter a frame (start timing)
* @param frame - Frame being entered
* @param at - Timestamp when frame was entered
*/
enterFrame(frame: Frame, at: number): void;
/**
* Leave a frame (end timing)
* @param frame - Frame being left
* @param at - Timestamp when frame was left
*/
leaveFrame(frame: Frame, at: number): void;
/** Build the final profile from collected data */
build(): Profile;
}
/**
* Builder for sampled profiles (periodic sampling data)
* Used for profiles that capture stack samples at regular intervals
*/
class StackListProfileBuilder {
/**
* Create a new stack list profile builder
* @param valueFormatter - Formatter for displaying sample values
*/
constructor(valueFormatter?: ValueFormatter);
/**
* Append a stack sample
* @param stack - Array of frames representing the call stack
* @param weight - Weight/duration of this sample
*/
appendSample(stack: Frame[], weight: number): void;
/** Build the final profile from collected samples */
build(): Profile;
}Type definitions for remapping symbols to source locations.
/**
* Function type for remapping frame symbols
* Used to map minified/compiled symbols back to source names and locations
*/
type SymbolRemapper = (
frame: Frame
) => {
name?: string;
file?: string;
line?: number;
col?: number;
} | null;Classes for formatting profile values for display.
/**
* Base interface for formatting profile values
*/
interface ValueFormatter {
/** Format a numeric value for display */
format(v: number): string;
/** Get the unit string (e.g., 'ms', 'bytes') */
unit: string;
}
/**
* Formatter for time values with appropriate unit scaling
*/
class TimeFormatter implements ValueFormatter {
unit: string;
format(v: number): string;
}
/**
* Formatter for byte/memory values with appropriate unit scaling
*/
class ByteFormatter implements ValueFormatter {
unit: string;
format(v: number): string;
}
/**
* Pass-through formatter that displays raw numeric values
*/
class RawValueFormatter implements ValueFormatter {
unit: string;
format(v: number): string;
}Usage Examples:
import {
Profile,
Frame,
CallTreeProfileBuilder,
StackListProfileBuilder,
TimeFormatter
} from 'speedscope';
// Create frames for profiling data
const mainFrame = new Frame({
key: 'main',
name: 'main',
file: 'app.js',
line: 1
});
const helperFrame = new Frame({
key: 'helper',
name: 'helper',
file: 'utils.js',
line: 15
});
// Build a call tree profile
const builder = new CallTreeProfileBuilder(new TimeFormatter());
builder.enterFrame(mainFrame, 0);
builder.enterFrame(helperFrame, 10);
builder.leaveFrame(helperFrame, 50);
builder.leaveFrame(mainFrame, 100);
const profile = builder.build();
profile.setName('My Profile');
// Create a profile group
const profileGroup = {
name: 'Application Profile',
indexToView: 0,
profiles: [profile]
};
// Build a sampled profile
const sampledBuilder = new StackListProfileBuilder(new TimeFormatter());
sampledBuilder.appendSample([mainFrame, helperFrame], 40);
sampledBuilder.appendSample([mainFrame], 20);
const sampledProfile = sampledBuilder.build();// Core profile data structures
type ProfileData = CallTreeProfile | SampledProfile;
interface CallTreeProfile {
type: 'call-tree';
root: CallTreeNode;
}
interface SampledProfile {
type: 'sampled';
samples: StackSample[];
}
interface StackSample {
stack: Frame[];
weight: number;
timestamp?: number;
}Install with Tessl CLI
npx tessl i tessl/npm-speedscope