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.
10- const enum Constants {
11- bufferLength = 256
12- }
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 ) ;
8+ // Measurements are recorded as totals, the average is calculated when the final measurements
9+ // are created.
10+ interface ICumulativeMeasurement {
11+ total : number ;
12+ min : number ;
13+ max : number ;
14+ }
15+ const totalKeydownTime : ICumulativeMeasurement = { total : 0 , min : Number . MAX_VALUE , max : 0 } ;
16+ const totalInputTime : ICumulativeMeasurement = { ...totalKeydownTime } ;
17+ const totalRenderTime : ICumulativeMeasurement = { ...totalKeydownTime } ;
18+ const totalInputLatencyTime : ICumulativeMeasurement = { ...totalKeydownTime } ;
1719 let measurementsCount = 0 ;
1820
21+
22+
1923 // The state of each event, this helps ensure the integrity of the measurement and that
2024 // something unexpected didn't happen that could skew the measurement.
2125 const enum EventPhase {
@@ -107,10 +111,6 @@ export namespace inputLatency {
107111 * Record the input latency sample if it's ready.
108112 */
109113 function record ( ) {
110- // Skip recording this frame if the buffer is full
111- if ( measurementsCount >= Constants . bufferLength ) {
112- return ;
113- }
114114 // Selection and render must have finished to record
115115 if ( state . selection !== EventPhase . Finished || state . render !== EventPhase . Finished ) {
116116 return ;
@@ -126,10 +126,10 @@ export namespace inputLatency {
126126 performance . measure ( 'render' , 'render/start' , 'render/end' ) ;
127127 performance . measure ( 'inputlatency' , 'inputlatency/start' , 'inputlatency/end' ) ;
128128
129- measurementsKeydown [ measurementsCount ] = performance . getEntriesByName ( 'keydown' ) [ 0 ] . duration ;
130- measurementsInput [ measurementsCount ] = performance . getEntriesByName ( 'input' ) [ 0 ] . duration ;
131- measurementsRender [ measurementsCount ] = performance . getEntriesByName ( 'render' ) [ 0 ] . duration ;
132- measurementsInputLatency [ measurementsCount ] = performance . getEntriesByName ( 'inputlatency' ) [ 0 ] . duration ;
129+ addMeasure ( 'keydown' , totalKeydownTime ) ;
130+ addMeasure ( 'input' , totalInputTime ) ;
131+ addMeasure ( 'render' , totalRenderTime ) ;
132+ addMeasure ( 'inputlatency' , totalInputLatencyTime ) ;
133133
134134 // console.info(
135135 // `input latency=${measurementsInputLatency[measurementsCount].toFixed(1)} [` +
@@ -146,6 +146,13 @@ export namespace inputLatency {
146146 } , 0 ) ;
147147 }
148148
149+ function addMeasure ( entryName : string , cumulativeMeasurement : ICumulativeMeasurement ) : void {
150+ const duration = performance . getEntriesByName ( entryName ) [ 0 ] . duration ;
151+ cumulativeMeasurement . total += duration ;
152+ cumulativeMeasurement . min = Math . min ( cumulativeMeasurement . min , duration ) ;
153+ cumulativeMeasurement . max = Math . max ( cumulativeMeasurement . max , duration ) ;
154+ }
155+
149156 /**
150157 * Clear the current sample.
151158 */
@@ -193,39 +200,37 @@ export namespace inputLatency {
193200 return undefined ;
194201 }
195202
196- // Calculate the average, min and max of each measurement
203+ // Assemble the result
197204 const result = {
198- keydown : createSingleMeasurement ( ) ,
199- input : createSingleMeasurement ( ) ,
200- render : createSingleMeasurement ( ) ,
201- total : createSingleMeasurement ( ) ,
205+ keydown : cumulativeToFinalMeasurement ( totalKeydownTime ) ,
206+ input : cumulativeToFinalMeasurement ( totalInputTime ) ,
207+ render : cumulativeToFinalMeasurement ( totalRenderTime ) ,
208+ total : cumulativeToFinalMeasurement ( totalInputLatencyTime ) ,
202209 sampleCount : measurementsCount
203210 } ;
204- for ( let i = 0 ; i < result . sampleCount ; i ++ ) {
205- result . keydown . average += measurementsKeydown [ i ] ;
206- result . input . average += measurementsInput [ i ] ;
207- result . render . average += measurementsRender [ i ] ;
208- result . total . average += measurementsInputLatency [ i ] ;
209- result . keydown . min = Math . min ( result . keydown . min , measurementsKeydown [ i ] ) ;
210- result . input . min = Math . min ( result . input . min , measurementsInput [ i ] ) ;
211- result . render . min = Math . min ( result . render . min , measurementsRender [ i ] ) ;
212- result . total . min = Math . min ( result . total . min , measurementsInputLatency [ i ] ) ;
213- result . keydown . max = Math . max ( result . keydown . max , measurementsKeydown [ i ] ) ;
214- result . input . max = Math . max ( result . input . max , measurementsInput [ i ] ) ;
215- result . render . max = Math . max ( result . render . max , measurementsRender [ i ] ) ;
216- result . total . max = Math . max ( result . total . max , measurementsInputLatency [ i ] ) ;
217- }
218- result . keydown . average /= result . sampleCount ;
219- result . input . average /= result . sampleCount ;
220- result . render . average /= result . sampleCount ;
221- result . total . average /= result . sampleCount ;
222211
212+ // Clear the cumulative measurements
213+ clearCumulativeMeasurement ( totalKeydownTime ) ;
214+ clearCumulativeMeasurement ( totalInputTime ) ;
215+ clearCumulativeMeasurement ( totalRenderTime ) ;
216+ clearCumulativeMeasurement ( totalInputLatencyTime ) ;
223217 measurementsCount = 0 ;
218+
224219 return result ;
225220 }
226221
227- function createSingleMeasurement ( ) : IInputLatencySingleMeasurement {
228- return { average : 0 , min : Number . MAX_VALUE , max : 0 } ;
222+ function cumulativeToFinalMeasurement ( cumulative : ICumulativeMeasurement ) : IInputLatencySingleMeasurement {
223+ return {
224+ average : cumulative . total / measurementsCount ,
225+ max : cumulative . max ,
226+ min : cumulative . min ,
227+ } ;
228+ }
229+
230+ function clearCumulativeMeasurement ( cumulative : ICumulativeMeasurement ) : void {
231+ cumulative . total = 0 ;
232+ cumulative . min = Number . MAX_VALUE ;
233+ cumulative . max = 0 ;
229234 }
230235
231236}
0 commit comments