55
66export namespace inputLatency {
77
8+ // Measurements are recorded in typed arrays with a fixed buffer length to their own impact on
9+ // input latency.
810 const enum Constants {
911 bufferLength = 256
1012 }
13+ const measurementsKeydown = new Float32Array ( Constants . bufferLength ) ;
14+ const measurementsInput = new Float32Array ( Constants . bufferLength ) ;
15+ const measurementsRender = new Float32Array ( Constants . bufferLength ) ;
16+ const measurementsInputLatency = new Float32Array ( Constants . bufferLength ) ;
17+ let measurementsCount = 0 ;
1118
19+ // The state of each event, this helps ensure the integrity of the measurement and that
20+ // something unexpected didn't happen that could skew the measurement.
1221 const enum EventPhase {
1322 Before = 0 ,
1423 InProgress = 1 ,
1524 Finished = 2
1625 }
17-
1826 const state = {
1927 keydown : EventPhase . Before ,
2028 input : EventPhase . Before ,
2129 render : EventPhase . Before ,
2230 selection : EventPhase . Before
2331 } ;
2432
25- const measurementsKeydown = new Float32Array ( Constants . bufferLength ) ;
26- const measurementsInput = new Float32Array ( Constants . bufferLength ) ;
27- const measurementsRender = new Float32Array ( Constants . bufferLength ) ;
28- const measurementsInputLatency = new Float32Array ( Constants . bufferLength ) ;
29- let measurementsCount = 0 ;
30-
33+ /**
34+ * Mark the start of the keydown event.
35+ */
3136 export function markKeydownStart ( ) {
3237 performance . mark ( 'inputlatency/start' ) ;
3338 performance . mark ( 'keydown/start' ) ;
3439 state . keydown = EventPhase . InProgress ;
3540 queueMicrotask ( ( ) => markKeydownEnd ( ) ) ;
3641 }
3742
43+ /**
44+ * Mark the end of the keydown event.
45+ */
3846 function markKeydownEnd ( ) {
3947 // Only measure the first render after keyboard input
4048 performance . mark ( 'keydown/end' ) ;
4149 state . keydown = EventPhase . Finished ;
4250 }
4351
52+ /**
53+ * Mark the start of the input event.
54+ */
4455 export function markInputStart ( ) {
4556 performance . mark ( 'input/start' ) ;
4657 state . input = EventPhase . InProgress ;
4758 }
4859
60+ /**
61+ * Mark the end of the input event.
62+ */
4963 export function markInputEnd ( ) {
5064 queueMicrotask ( ( ) => {
5165 performance . mark ( 'input/end' ) ;
5266 state . input = EventPhase . Finished ;
5367 } ) ;
5468 }
5569
70+ /**
71+ * Mark the start of the animation frame performing the rendering.
72+ */
5673 export function markRenderStart ( ) {
5774 // Render may be triggered during input, but we only measure the following animation frame
5875 if ( state . keydown === EventPhase . Finished && state . input === EventPhase . Finished && state . render === EventPhase . Before ) {
@@ -63,17 +80,32 @@ export namespace inputLatency {
6380 }
6481 }
6582
83+ /**
84+ * Mark the end of the animation frame performing the rendering.
85+ *
86+ * An input latency sample is complete when both the textarea selection change event and the
87+ * animation frame performing the rendering has triggered.
88+ */
6689 function markRenderEnd ( ) {
6790 performance . mark ( 'render/end' ) ;
6891 state . render = EventPhase . Finished ;
6992 record ( ) ;
7093 }
7194
95+ /**
96+ * Mark when the editor textarea selection change event occurs.
97+ *
98+ * An input latency sample is complete when both the textarea selection change event and the
99+ * animation frame performing the rendering has triggered.
100+ */
72101 export function markTextareaSelection ( ) {
73102 state . selection = EventPhase . Finished ;
74103 record ( ) ;
75104 }
76105
106+ /**
107+ * Record the input latency sample if it's ready.
108+ */
77109 function record ( ) {
78110 // Skip recording this frame if the buffer is full
79111 if ( measurementsCount >= Constants . bufferLength ) {
@@ -113,6 +145,10 @@ export namespace inputLatency {
113145 } ) ;
114146 }
115147 setInterval ( ( ) => console . log ( getAndClearMeasurements ( ) ) , 10000 ) ;
148+
149+ /**
150+ * Clear the current sample.
151+ */
116152 function reset ( ) {
117153 performance . clearMarks ( 'keydown/start' ) ;
118154 performance . clearMarks ( 'keydown/end' ) ;
@@ -148,6 +184,10 @@ export namespace inputLatency {
148184 max : number ;
149185 }
150186
187+ /**
188+ * Gets all input latency samples and clears the internal buffers to start recording a new set
189+ * of samples.
190+ */
151191 export function getAndClearMeasurements ( ) : IInputLatencyMeasurements | undefined {
152192 if ( measurementsCount === 0 ) {
153193 return undefined ;
0 commit comments