Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve documentation #60

Merged
merged 6 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ An APM library for detecting UI jank in Flutter for mobile (Android/iOS).

Building smooth APPs with Flutter is easy, but as your APP grows in complexity and faces a variety of user environments and devices, ensuring smooth performance in production can be challenging. Even if your app runs smoothly locally, it doesn't guarantee the same for all users. `glance` helps collect stack traces during UI jank, allowing you to pinpoint the exact function causing the performance issue, so you can resolve it effectively.

`glance` detects UI jank during the build phase as well as through various callbacks, such as, `WidgetBindingObserver` callbacks, touch events, and method channel callbacks. These cover most cases that cause UI jank. It works only in release or profile builds when your application is built with the [`--split-debug-info` option](https://docs.flutter.dev/deployment/obfuscate#obfuscate-your-app).
`glance` detects UI jank during the rendering phase as well as through various callbacks, such as, `WidgetBindingObserver` callbacks, touch events, and method channel callbacks. These cover most cases that cause UI jank. It works only in release or profile builds when your application is built with the [`--split-debug-info` option](https://docs.flutter.dev/deployment/obfuscate#obfuscate-your-app).

## Getting Started

Expand Down
36 changes: 35 additions & 1 deletion lib/src/glance.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import 'package:glance/src/glance_impl.dart';
import 'package:flutter/widgets.dart' show WidgetsFlutterBinding;

/// A custom binding that connects [WidgetsFlutterBinding] and [Glance] to detect
/// UI jank during the build phase and from "external sources" such as callbacks from
/// UI jank during the rendering phase and from "external sources" such as callbacks from
/// [WidgetsBindingObserver], touch events, and channel messages from the platform.
class GlanceWidgetBinding extends WidgetsFlutterBinding
with GlanceWidgetBindingMixin {
Expand Down Expand Up @@ -88,6 +88,40 @@ class GlanceConfiguration {
/// After obtaining the [JankReport.stackTrace], you can symbolize it using the `flutter symbolize` command.
/// For more details, see https://docs.flutter.dev/deployment/obfuscate#read-an-obfuscated-stack-trace.
/// You can save the stack traces to files or upload them to your server and symbolize them later.
///
/// For example:
/// ```dart
/// // Implement your `JankDetectedReporter`
/// class MyJankDetectedReporter extends JankDetectedReporter {
/// @override
/// void report(JankReport info) {
/// final stackTrace = info.stackTrace.toString();
/// // Save the stack traces to a file, or upload them to your server,
/// // symbolize them using the `flutter symbolize` command.
/// }
/// }
///
/// void main() {
/// // Call `GlanceWidgetBinding.ensureInitialized()` first
/// GlanceWidgetBinding.ensureInitialized();
/// // Start UI Jank Detection
/// Glance.instance.start(config: GlanceConfiguration(reporters: [MyJankDetectedReporter()]));
///
/// runApp(const MyApp());
/// }
/// ```
///
/// ## How it works
/// `glance` starts a dedicated [Isolate] internally to capture Dart UI thread stack traces using native stack unwinding.
/// Refer to [Sampler] for more details.
///
/// To detect UI jank, `glance` extends [WidgetsFlutterBinding] and monitors execution time between [WidgetsFlutterBinding.handleBeginFrame]
/// and [WidgetsFlutterBinding.handleDrawFrame] during the rendering phase. It also tracks various callbacks such as [WidgetBindingObserver],
/// touch events, and method channel callbacks' invocations, checking each against its execution time.
/// Jank is detected when the execution time exceeds the [GlanceConfiguration.jankThreshold].
///
/// Upon detecting jank, `glance` fetches stack traces from the [Sampler] during the jank period and reconstructs them into Dart stack traces.
/// These are then reported to the [GlanceReporter], specified via [GlanceConfiguration.reporters].
abstract class Glance {
Glance._();

Expand Down
6 changes: 3 additions & 3 deletions lib/src/glance_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ typedef HandleDrawFrameEndCallback = void Function(

typedef CheckJankCallback = void Function(int start, int end);

/// Besides the build phase check ([handleBeginFrame] to [handleDrawFrame]), we only
/// Besides the rendering phase check ([handleBeginFrame] to [handleDrawFrame]), we only
/// override the functions that handle callbacks from the [PlatformDispatcher].
/// Other callbacks are handled by the channel called ([_DefaultBinaryMessengerProxy]).
mixin GlanceWidgetBindingMixin on WidgetsFlutterBinding {
Expand All @@ -307,8 +307,8 @@ mixin GlanceWidgetBindingMixin on WidgetsFlutterBinding {
T traceFunctionCall<T>(T Function() func) {
int start = Timeline.now;
final ret = func();
// Only check jank if not in build phase, because if it is in buid phase,
// the jank has been checked by the build phase jank check
// Only check jank if not in rendering phase, because if it is in rendering phase,
// the jank has been checked by the rendering phase jank check
if (schedulerPhase == SchedulerPhase.idle) {
_onCheckJank?.call(start, Timeline.now);
}
Expand Down
Loading