PerformanceTracker
The PerformanceTracker class collects and analyzes frame timing data to provide comprehensive performance metrics. It maintains a rolling history of frame times and FPS values, enabling percentile calculations, variance detection, and dropped frame tracking.
Overview
import { PerformanceTracker } from '@3lens/core';
// Create tracker with defaults (300 samples, 60 FPS target)
const tracker = new PerformanceTracker();
// Or with custom settings
const customTracker = new PerformanceTracker(600, 144); // 600 samples, 144 FPS target2
3
4
5
6
7
Constructor
constructor(maxSamples?: number, targetFps?: number)| Parameter | Type | Default | Description |
|---|---|---|---|
maxSamples | number | 300 | Maximum number of frame samples to keep in history |
targetFps | number | 60 | Target frame rate for budget calculations |
Methods
recordFrame()
Records a frame's timing data and updates all internal histories.
recordFrame(cpuTimeMs: number, timestamp: number): void| Parameter | Type | Description |
|---|---|---|
cpuTimeMs | number | CPU time spent on this frame in milliseconds |
timestamp | number | Frame timestamp from performance.now() |
Example:
function animate(timestamp: number) {
const startTime = performance.now();
// Your render logic here
renderer.render(scene, camera);
const cpuTime = performance.now() - startTime;
tracker.recordFrame(cpuTime, timestamp);
requestAnimationFrame(animate);
}2
3
4
5
6
7
8
9
10
11
getDeltaTime()
Returns the time elapsed since the last recorded frame.
getDeltaTime(timestamp: number): number| Parameter | Type | Description |
|---|---|---|
timestamp | number | Current frame timestamp |
Returns: Delta time in milliseconds (defaults to 16.67ms for the first frame).
getMetrics()
Returns comprehensive performance metrics based on current and historical data.
getMetrics(cpuTimeMs: number): PerformanceMetricsReturns: A PerformanceMetrics object with the following properties:
| Property | Type | Description |
|---|---|---|
fps | number | Current instantaneous FPS |
fpsSmoothed | number | Rolling average FPS |
fpsMin | number | Minimum FPS in history |
fpsMax | number | Maximum FPS in history |
fps1PercentLow | number | 1% low FPS (99th percentile frame time) |
frameBudgetUsed | number | Percentage of frame budget used (0-100) |
targetFrameTimeMs | number | Target frame time based on target FPS |
frameTimeVariance | number | Standard deviation of frame times |
isSmooth | boolean | Whether frame is within 110% of target |
droppedFrames | number | Consecutive dropped frames count |
Example:
const metrics = tracker.getMetrics(cpuTimeMs);
if (!metrics.isSmooth) {
console.warn(`Frame budget exceeded: ${metrics.frameBudgetUsed.toFixed(1)}%`);
}
console.log(`FPS: ${metrics.fps} (1% low: ${metrics.fps1PercentLow})`);2
3
4
5
6
7
getPercentile()
Calculates a percentile value from the frame time history.
getPercentile(percentile: number): number| Parameter | Type | Description |
|---|---|---|
percentile | number | Percentile to calculate (0-100) |
Returns: Frame time at the specified percentile in milliseconds.
Example:
const p50 = tracker.getPercentile(50); // Median frame time
const p95 = tracker.getPercentile(95); // 95th percentile
const p99 = tracker.getPercentile(99); // Worst 1% of frames2
3
getAverageFrameTime()
Returns the average frame time across all samples in history.
getAverageFrameTime(): numberReturns: Average frame time in milliseconds.
getAverageFps()
Returns the average FPS across all samples in history.
getAverageFps(): numberReturns: Average FPS value.
getMinFps()
Returns the minimum FPS value in the history.
getMinFps(): numberReturns: Minimum FPS recorded.
getMaxFps()
Returns the maximum FPS value in the history.
getMaxFps(): numberReturns: Maximum FPS recorded.
get1PercentLowFps()
Returns the 1% low FPS, calculated from the 99th percentile frame time.
get1PercentLowFps(): numberReturns: FPS value representing the worst 1% of frames.
Understanding 1% Low
The 1% low FPS is a better indicator of stuttering than average FPS. It represents how the worst frames perform, which directly impacts perceived smoothness.
getVariance()
Returns the standard deviation of frame times, indicating frame time consistency.
getVariance(): numberReturns: Frame time variance (standard deviation) in milliseconds.
Interpreting Variance
- < 2ms: Excellent consistency
- 2-5ms: Good, minor jitter
- 5-10ms: Noticeable stuttering
- > 10ms: Significant frame time instability
reset()
Clears all frame history and resets counters.
reset(): voidExample:
// Reset when switching scenes
function loadNewScene() {
tracker.reset();
// Load scene...
}2
3
4
5
Frame Budget Calculation
The tracker calculates frame budget usage based on the target FPS:
Frame Budget % = (cpuTimeMs / targetFrameTimeMs) × 100For a 60 FPS target:
- Target frame time: 16.67ms
- 10ms frame → 60% budget used
- 20ms frame → 120% budget used (over budget)
Dropped Frame Detection
A frame is considered "dropped" when it takes more than 150% of the target frame time:
// For 60 FPS target (16.67ms):
// Frame > 25ms is marked as dropped
if (cpuTimeMs > targetFrameTimeMs * 1.5) {
droppedFrames++;
} else {
droppedFrames = 0; // Reset on smooth frame
}2
3
4
5
6
7
8
Integration with 3Lens
The PerformanceTracker is used internally by DevtoolProbe to populate frame statistics:
// PerformanceTracker is automatically created and managed
const probe = createProbe({ /* config */ });
// Access metrics through frame stats
probe.on('frame', (stats) => {
console.log(stats.performance.fps);
console.log(stats.performance.fps1PercentLow);
console.log(stats.performance.frameBudgetUsed);
});2
3
4
5
6
7
8
9
Architecture
┌─────────────────────────────────────────────────────────────┐
│ PerformanceTracker │
├─────────────────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Frame Times │ │ FPS History │ │ Dropped Frame │ │
│ │ Array │ │ Array │ │ Counter │ │
│ │ (maxSamples) │ │ (maxSamples) │ │ │ │
│ └──────┬───────┘ └──────┬───────┘ └────────┬─────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ getMetrics() │ │
│ │ • FPS (instant, smoothed, min, max, 1% low) │ │
│ │ • Frame budget usage │ │
│ │ • Variance calculation │ │
│ │ • Smoothness detection │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Best Practices
Choose Appropriate Sample Count
// Mobile/low-power: fewer samples for memory efficiency
const mobileTracker = new PerformanceTracker(100, 30);
// Desktop: more samples for better percentile accuracy
const desktopTracker = new PerformanceTracker(600, 60);
// VR: high refresh rate target
const vrTracker = new PerformanceTracker(300, 90);2
3
4
5
6
7
8
Monitor 1% Low for Stuttering
const metrics = tracker.getMetrics(cpuTimeMs);
// Alert when 1% low is significantly below average
if (metrics.fps1PercentLow < metrics.fpsSmoothed * 0.7) {
console.warn('Significant frame time spikes detected');
}2
3
4
5
6
Use Variance for Consistency Checks
const variance = tracker.getVariance();
if (variance > 5) {
console.warn(`High frame time variance: ${variance.toFixed(2)}ms`);
// Investigate causes: GC, complex calculations, etc.
}2
3
4
5
6
See Also
- FrameStats Interface - Complete frame statistics structure
- Performance Thresholds - Configuring warning thresholds
- Sampling Configuration - Frame sampling options
- DevtoolProbe - Main probe class that uses PerformanceTracker