1
1
import 'dart:async' ;
2
+ import 'dart:developer' show log;
2
3
import 'dart:ui' ;
3
4
4
5
import 'package:flutter/widgets.dart' ;
@@ -18,14 +19,14 @@ enum UiTraceType {
18
19
@internal
19
20
class InstabugScreenRenderManager {
20
21
WidgetsBinding ? _widgetsBinding;
21
- late int _buildTime ;
22
- late int _rasterTime ;
23
- late int _totalTime ;
22
+ late int _buildTimeMs ;
23
+ late int _rasterTimeMs ;
24
+ late int _totalTimeMs ;
24
25
late TimingsCallback _timingsCallback;
25
26
late InstabugScreenRenderData _screenRenderForAutoUiTrace;
26
27
late InstabugScreenRenderData _screenRenderForCustomUiTrace;
27
- int _slowFramesTotalDurationMs = 0 ;
28
- int _frozenFramesTotalDurationMs = 0 ;
28
+ int _slowFramesTotalDurationMicro = 0 ;
29
+ int _frozenFramesTotalDurationMicro = 0 ;
29
30
int ? _epochOffset;
30
31
bool _isTimingsListenerAttached = false ;
31
32
bool screenRenderEnabled = false ;
@@ -42,7 +43,7 @@ class InstabugScreenRenderManager {
42
43
/// Default frozen frame threshold in milliseconds (700ms)
43
44
final _frozenFrameThresholdMs = 700 ;
44
45
45
- final _microsecondsPerMillisecond = 1000 ;
46
+ // final _microsecondsPerMillisecond = 1000;
46
47
47
48
InstabugScreenRenderManager ._();
48
49
@@ -75,46 +76,45 @@ class InstabugScreenRenderManager {
75
76
}
76
77
}
77
78
78
- /// analyze frame data in order to detect slow/ frozen frame .
79
+ /// Analyze frame data to detect slow or frozen frames efficiently .
79
80
@visibleForTesting
80
81
void analyzeFrameTiming (FrameTiming frameTiming) {
81
- _buildTime = frameTiming.buildDuration.inMilliseconds;
82
- _rasterTime = frameTiming.rasterDuration.inMilliseconds;
83
- _totalTime = frameTiming.totalSpan.inMilliseconds;
84
-
85
- if (_isUiFrozen) {
86
- _frozenFramesTotalDurationMs += _buildTime;
87
- } else if (_isRasterFrozen) {
88
- _frozenFramesTotalDurationMs += _rasterTime;
89
- } else if (_isTotalTimeLarge) {
90
- _frozenFramesTotalDurationMs += _totalTime;
91
- }
92
- if (_isUiSlow) {
93
- _slowFramesTotalDurationMs += _buildTime;
94
- } else if (_isRasterSlow) {
95
- _slowFramesTotalDurationMs += _rasterTime;
96
- }
82
+ _buildTimeMs = frameTiming.buildDuration.inMilliseconds;
83
+ _rasterTimeMs = frameTiming.rasterDuration.inMilliseconds;
84
+ _totalTimeMs = frameTiming.totalSpan.inMilliseconds;
97
85
98
- if (_isUiDelayed) {
86
+ if (_isTotalTimeLarge) {
87
+ final micros = frameTiming.totalSpan.inMicroseconds;
88
+ _frozenFramesTotalDurationMicro += micros;
99
89
_onDelayedFrameDetected (
100
90
_getMicrosecondsSinceEpoch (
101
- frameTiming.timestampInMicroseconds (FramePhase .buildStart ),
91
+ frameTiming.timestampInMicroseconds (FramePhase .vsyncStart ),
102
92
),
103
- _buildTime ,
93
+ micros ,
104
94
);
105
- } else if (_isRasterDelayed) {
95
+ return ;
96
+ }
97
+
98
+ if (_isUiSlow) {
99
+ final micros = frameTiming.buildDuration.inMicroseconds;
100
+ _slowFramesTotalDurationMicro += micros;
106
101
_onDelayedFrameDetected (
107
102
_getMicrosecondsSinceEpoch (
108
- frameTiming.timestampInMicroseconds (FramePhase .rasterStart ),
103
+ frameTiming.timestampInMicroseconds (FramePhase .buildStart ),
109
104
),
110
- _rasterTime ,
105
+ micros ,
111
106
);
112
- } else if (_isTotalTimeLarge) {
107
+ return ;
108
+ }
109
+
110
+ if (_isRasterSlow) {
111
+ final micros = frameTiming.rasterDuration.inMicroseconds;
112
+ _slowFramesTotalDurationMicro += micros;
113
113
_onDelayedFrameDetected (
114
114
_getMicrosecondsSinceEpoch (
115
- frameTiming.timestampInMicroseconds (FramePhase .vsyncStart ),
115
+ frameTiming.timestampInMicroseconds (FramePhase .rasterStart ),
116
116
),
117
- _totalTime ,
117
+ micros ,
118
118
);
119
119
}
120
120
}
@@ -215,23 +215,15 @@ class InstabugScreenRenderManager {
215
215
216
216
/// --------------------------- private methods ---------------------
217
217
218
- bool get _isUiDelayed => _isUiSlow || _isUiFrozen;
219
-
220
- bool get _isRasterDelayed => _isRasterSlow || _isRasterFrozen;
221
-
222
218
bool get _isUiSlow =>
223
- _buildTime > _slowFrameThresholdMs &&
224
- _buildTime < _frozenFrameThresholdMs;
219
+ _buildTimeMs > _slowFrameThresholdMs &&
220
+ _buildTimeMs < _frozenFrameThresholdMs;
225
221
226
222
bool get _isRasterSlow =>
227
- _rasterTime > _slowFrameThresholdMs &&
228
- _rasterTime < _frozenFrameThresholdMs;
223
+ _rasterTimeMs > _slowFrameThresholdMs &&
224
+ _rasterTimeMs < _frozenFrameThresholdMs;
229
225
230
- bool get _isTotalTimeLarge => _totalTime >= _frozenFrameThresholdMs;
231
-
232
- bool get _isUiFrozen => _buildTime >= _frozenFrameThresholdMs;
233
-
234
- bool get _isRasterFrozen => _rasterTime >= _frozenFrameThresholdMs;
226
+ bool get _isTotalTimeLarge => _totalTimeMs >= _frozenFrameThresholdMs;
235
227
236
228
/// Calculate the target time for the frame to be drawn in milliseconds based on the device refresh rate.
237
229
double _targetMsPerFrame (double displayRefreshRate) =>
@@ -302,18 +294,21 @@ class InstabugScreenRenderManager {
302
294
303
295
/// Reset the memory cashed data
304
296
void _resetCachedFrameData () {
305
- _slowFramesTotalDurationMs = 0 ;
306
- _frozenFramesTotalDurationMs = 0 ;
297
+ _slowFramesTotalDurationMicro = 0 ;
298
+ _frozenFramesTotalDurationMicro = 0 ;
307
299
_delayedFrames.clear ();
308
300
}
309
301
310
302
/// Save Slow/Frozen Frames data
311
- void _onDelayedFrameDetected (int startTime, int durationInMilliseconds) {
303
+ void _onDelayedFrameDetected (int startTime, int durationInMicroseconds) {
304
+ log (
305
+ "${durationInMicroseconds >= 700000 ? "🚨Frozen" : "⚠️Slow" } Frame Detected (startTime: $startTime , duration: $durationInMicroseconds µs)" ,
306
+ name: tag,
307
+ );
312
308
_delayedFrames.add (
313
309
InstabugFrameData (
314
310
startTime,
315
- durationInMilliseconds *
316
- _microsecondsPerMillisecond, // Convert duration from milliseconds to microSeconds
311
+ durationInMicroseconds,
317
312
),
318
313
);
319
314
}
@@ -325,6 +320,10 @@ class InstabugScreenRenderManager {
325
320
InstabugScreenRenderData screenRenderData,
326
321
) async {
327
322
try {
323
+ log (
324
+ "reportScreenRenderForCustomUiTrace $screenRenderData " ,
325
+ name: tag,
326
+ );
328
327
await APM .endScreenRenderForCustomUiTrace (screenRenderData);
329
328
return true ;
330
329
} catch (error, stackTrace) {
@@ -343,7 +342,12 @@ class InstabugScreenRenderManager {
343
342
// Save the end time for the running ui trace, it's only needed in Android SDK.
344
343
screenRenderData.saveEndTime ();
345
344
345
+ log (
346
+ "reportScreenRenderForAutoUiTrace $screenRenderData " ,
347
+ name: tag,
348
+ );
346
349
await APM .endScreenRenderForAutoUiTrace (screenRenderData);
350
+
347
351
return true ;
348
352
} catch (error, stackTrace) {
349
353
_logExceptionErrorAndStackTrace (error, stackTrace);
@@ -370,9 +374,9 @@ class InstabugScreenRenderManager {
370
374
/// or synced with the native side.
371
375
void _updateCustomUiData () {
372
376
_screenRenderForCustomUiTrace.slowFramesTotalDurationMicro +=
373
- _slowFramesTotalDurationMs * _microsecondsPerMillisecond ;
377
+ _slowFramesTotalDurationMicro ;
374
378
_screenRenderForCustomUiTrace.frozenFramesTotalDurationMicro +=
375
- _frozenFramesTotalDurationMs * _microsecondsPerMillisecond ;
379
+ _frozenFramesTotalDurationMicro ;
376
380
_screenRenderForCustomUiTrace.frameData.addAll (_delayedFrames);
377
381
}
378
382
@@ -385,9 +389,9 @@ class InstabugScreenRenderManager {
385
389
/// or synced with the native side.
386
390
void _updateAutoUiData () {
387
391
_screenRenderForAutoUiTrace.slowFramesTotalDurationMicro +=
388
- _slowFramesTotalDurationMs * _microsecondsPerMillisecond ;
392
+ _slowFramesTotalDurationMicro ;
389
393
_screenRenderForAutoUiTrace.frozenFramesTotalDurationMicro +=
390
- _frozenFramesTotalDurationMs * _microsecondsPerMillisecond ;
394
+ _frozenFramesTotalDurationMicro ;
391
395
_screenRenderForAutoUiTrace.frameData.addAll (_delayedFrames);
392
396
}
393
397
@@ -426,9 +430,7 @@ class InstabugScreenRenderManager {
426
430
@visibleForTesting
427
431
void setFrameData (InstabugScreenRenderData data) {
428
432
_delayedFrames.addAll (data.frameData);
429
- _frozenFramesTotalDurationMs =
430
- data.frozenFramesTotalDurationMicro ~ / _microsecondsPerMillisecond;
431
- _slowFramesTotalDurationMs =
432
- data.slowFramesTotalDurationMicro ~ / _microsecondsPerMillisecond;
433
+ _frozenFramesTotalDurationMicro = data.frozenFramesTotalDurationMicro;
434
+ _slowFramesTotalDurationMicro = data.slowFramesTotalDurationMicro;
433
435
}
434
436
}
0 commit comments