Skip to content

Commit d435299

Browse files
committed
track total, slow and frozen frames
1 parent b63839d commit d435299

File tree

2 files changed

+39
-47
lines changed

2 files changed

+39
-47
lines changed
Lines changed: 38 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import 'dart:ui';
2-
32
import 'package:flutter/widgets.dart';
43
import 'package:sentry/sentry.dart';
54

@@ -11,66 +10,61 @@ class FrameTracker {
1110
}) : _binding = binding;
1211

1312
final WidgetsBinding _binding;
14-
bool? _isSupported;
15-
16-
// Checks wether [FrameTracker] is supported on this Flutter version
17-
bool get isSupported {
18-
// TODO: Check if this works on web
19-
try {
20-
(_binding.window as dynamic).frameData.frameNumber as int;
21-
} on NoSuchMethodError catch (_) {
22-
return _isSupported ??= false;
23-
}
24-
return _isSupported ??= true;
25-
}
2613

2714
SingletonFlutterWindow get window => _binding.window;
2815

2916
final Duration slowFrameThreshold;
3017
final Duration frozenFrameThreshold;
3118

32-
var startFrameNumber = -1;
33-
var endFrameNumber = -1;
19+
DateTime? _timeStamp;
3420

35-
void start() {
36-
if (!isSupported) {
21+
var _frameCount = 0;
22+
var _slowCount = 0;
23+
var _frozenCount = 0;
24+
25+
void _frameCallback(Duration _) {
26+
final timeStamp = _timeStamp;
27+
if (timeStamp == null) {
3728
return;
3829
}
39-
startFrameNumber = window.currentFrameNumber;
40-
}
4130

42-
List<SentryMeasurement>? finish() {
43-
if (!isSupported || startFrameNumber == -1) {
44-
// Either the current Flutter version doesn't support frame numbers yet
45-
// or frame tracking hasn't started.
46-
return null;
31+
// postFrameCallbacks are called just once,
32+
// so we have to add it each frame.
33+
_binding.addPostFrameCallback(_frameCallback);
34+
35+
final now = DateTime.now();
36+
_timeStamp = now;
37+
final duration = timeStamp.difference(now).abs();
38+
39+
if (duration > frozenFrameThreshold) {
40+
_frozenCount++;
41+
} else if (duration > slowFrameThreshold) {
42+
_slowCount++;
4743
}
48-
endFrameNumber = window.currentFrameNumber;
4944

50-
final metrics = _listToMetrics(
51-
startFrameNumber,
52-
endFrameNumber,
53-
);
54-
_reset();
55-
return metrics;
45+
_frameCount++;
5646
}
5747

58-
void _reset() {
59-
startFrameNumber = -1;
60-
endFrameNumber = -1;
48+
void start() {
49+
_timeStamp = DateTime.now();
50+
_binding.addPostFrameCallback(_frameCallback);
6151
}
6252

63-
static List<SentryMeasurement> _listToMetrics(
64-
int startFrameNumber,
65-
int endFrameNumber,
66-
) {
67-
final frameCount = endFrameNumber - startFrameNumber;
53+
List<SentryMeasurement> finish() {
54+
final metrics = [
55+
SentryMeasurement.totalFrames(_frameCount),
56+
SentryMeasurement.frozenFrames(_frozenCount),
57+
SentryMeasurement.slowFrames(_slowCount),
58+
];
6859

69-
return [SentryMeasurement.totalFrames(frameCount.toDouble())];
60+
_reset();
61+
return metrics;
7062
}
71-
}
7263

73-
extension _SingletonFlutterWindowExtension on SingletonFlutterWindow {
74-
// Code to make this compatible with Flutter < 2.8
75-
int get currentFrameNumber => (this as dynamic).frameData.frameNumber as int;
64+
void _reset() {
65+
_timeStamp = null;
66+
_frameCount = 0;
67+
_slowCount = 0;
68+
_frozenCount = 0;
69+
}
7670
}

flutter/lib/src/navigation/sentry_navigator_observer.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,7 @@ class SentryNavigatorObserver extends RouteObserver<PageRoute<dynamic>> {
179179
// ignore: invalid_use_of_internal_member
180180
final transaction = _transaction as SentryTracer;
181181
final measurements = _frameTracker.finish();
182-
if (measurements != null) {
183-
transaction.measurements.addAll(measurements);
184-
}
182+
transaction.measurements.addAll(measurements);
185183
}
186184
return await _transaction?.finish();
187185
}

0 commit comments

Comments
 (0)