| 18 | } |
| 19 | |
| 20 | getMetrics(): FpsMetrics | undefined { |
| 21 | if ( |
| 22 | this.frameDurations.length === 0 || |
| 23 | this.firstRenderTime === undefined || |
| 24 | this.lastRenderTime === undefined |
| 25 | ) { |
| 26 | return undefined |
| 27 | } |
| 28 | |
| 29 | const totalTimeMs = this.lastRenderTime - this.firstRenderTime |
| 30 | if (totalTimeMs <= 0) { |
| 31 | return undefined |
| 32 | } |
| 33 | |
| 34 | const totalFrames = this.frameDurations.length |
| 35 | const averageFps = totalFrames / (totalTimeMs / 1000) |
| 36 | |
| 37 | const sorted = this.frameDurations.slice().sort((a, b) => b - a) |
| 38 | const p99Index = Math.max(0, Math.ceil(sorted.length * 0.01) - 1) |
| 39 | const p99FrameTimeMs = sorted[p99Index]! |
| 40 | const low1PctFps = p99FrameTimeMs > 0 ? 1000 / p99FrameTimeMs : 0 |
| 41 | |
| 42 | return { |
| 43 | averageFps: Math.round(averageFps * 100) / 100, |
| 44 | low1PctFps: Math.round(low1PctFps * 100) / 100, |
| 45 | } |
| 46 | } |
| 47 | } |
| 48 | |