jank_scout 0.0.3
jank_scout: ^0.0.3 copied to clipboard
A performance-optimized, zero-dependency frame drop (jank) interception package for local Flutter development.
Jank Scout #
Jank Scout is a lightweight, high-performance frame drop interception and telemetry package built for local Flutter development. It passively monitors rendering pipeline events, identifies frame timing drops that overrun the frame budget, and formats diagnostic telemetry reports into the developer console.
Note
Unlike traditional APM packages or UI overlay extensions, Jank Scout is built to operate passively, cleanly, and safely.
Why Jank Scout? (The Problem It Solves) #
Modern Flutter performance profiling typically forces developers to choose between two sub-optimal approaches:
- VS. Flutter DevTools: While powerful, DevTools requires manual setup, launching separate browser tabs, keeping web sockets connected, and explicitly recording performance sessions. It is an active debugging utility rather than a passive, continuous checker. Jank Scout requires zero browser tabs and monitors your app passively, sending automated telemetry straight to your terminal as you develop.
- VS. Production APMs (e.g., Sentry, Firebase Performance): Heavy production performance monitoring frameworks are designed for live user monitoring. They add runtime overhead, make blocking network requests, introduce heavy dependency trees, and increase your final app size. Jank Scout is a local-only tool that uses native framework callbacks, has zero package dependencies, and completely self-destructs (100% tree-shaken out) during release compilation, leaving absolutely zero runtime or binary bloat.
Technical Differences and Key Capabilities #
- Passive Terminal Telemetry: There are no floating charts, graph windows, or overlay widgets blocking your touch boundaries or layout calculations. All diagnostics stream directly to the development console to keep your test environment clean.
- Compile-Time Production Safety:
Important
Every core monitoring route, callback hook, and telemetry string builder is wrapped inside strict compilation
assertboundaries. When compiling release builds, the entire package implementation is completely tree-shaken by the compiler—leaving zero execution path overhead, zero background thread activity, and zero binary size bloat. - Zero Third-Party Dependencies: Built completely using native Flutter SDK binding callbacks. It introduces no external dependencies to your project tree, preventing package-version conflicts and keeping your architecture clean.
- Bottleneck Remediation Guidance: Automatically divides latency reports into UI Thread (CPU Build) and Raster Thread (GPU) executions, providing dynamic structural diagnostic explanations to guide performance remediation.
- Telemetry Cooldown and Noise Suppression: Implements a
4msthreshold buffer to ignore minor hardware jitter, paired with a2.5-secondlogging cooldown per route to completely eliminate terminal log flooding.
Installation #
Add jank_scout to the dependency list in your project's pubspec.yaml file:
dependencies:
jank_scout: ^0.0.1
Or install it directly from your terminal:
flutter pub add jank_scout
Quick Start #
1. Initialize the Telemetry Engine #
Initialize the JankScout controller inside your application's main() entry function.
Warning
Ensure that WidgetsFlutterBinding.ensureInitialized() has been executed prior to calling the initialization method.
import 'package:flutter/material.dart';
import 'package:jank_scout/jank_scout.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
// Initialize JankScout targeting the device refresh rate (e.g., 60 FPS)
JankScout.initialize(targetFps: 60.0);
runApp(const MyApp());
}
2. Configure Navigator Attribution #
Add JankScoutObserver to your MaterialApp's navigatorObservers list to enable route-level telemetry mapping.
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Performance Testing App',
navigatorObservers: [JankScoutObserver()],
initialRoute: '/',
routes: {
'/': (context) => const HomeScreen(),
'/details': (context) => const DetailsScreen(),
},
);
}
}
Telemetry Report Format #
When a frame overrun is captured, a structured ASCII telemetry card is printed to the console:
+----------------------------------------------------------------------+
| TELEMETRY REPORT: 🚨 [PIPELINE CRITICAL INTERRUPT]
+----------------------------------------------------------------------+
| Target Route: /details
| Budget: 16.67 ms (Target FPS: 60)
| Frame Render Time: 76.50 ms (Overrun: 358.9%, +59.83 ms)
| Thread Breakdowns:
| - UI Thread (CPU Build): 68.20 ms
| - Raster Thread (GPU): 8.30 ms
+----------------------------------------------------------------------+
| Bottleneck Analysis:
| ❌ BOTTLENECK: UI Thread (CPU Boundary). Diagnostic: Excessive execution cycle detected on the Dart isolate runtime loop. Remediate by auditing synchronous serialization, unoptimized layout passes, or high-frequency state emissions violating state boundary conditions.
+----------------------------------------------------------------------+
Architectural Breakdown #
Jank Scout separates performance bottlenecks into the two primary execution domains of the Flutter rendering pipeline:
| Pipeline Thread | Description | Common Bottlenecks |
|---|---|---|
| UI Thread (CPU Build) | Executes all Dart application code, handles layout calculations, reconstructs widget trees, and produces layer trees. | • Heavy operations in build methods • Synchronous JSON parsing on the main isolate • Unoptimized state changes triggering deep subtree rebuilds |
| Raster Thread (GPU) | Receives the Layer tree from the UI thread, translates it into GPU instructions (via Skia or Impeller), and rasterizes it. | • Complex shape clipping • Excessive saveLayer compositions• Loading unoptimized high-resolution image assets |
Contributing #
Contributions are welcome! If you encounter any bugs, have feature requests, or want to improve the codebase:
- Reporting Bugs: Please open an issue on the GitHub repository detailing the problem, your Flutter environment, and steps to reproduce.
- Submitting Pull Requests: Fork the repository, create a descriptive branch, implement your changes (ensuring
flutter analyzepasses with zero issues), and open a pull request. - Local Testing: Use the included
example/project to verify modifications and test performance timings under both synchronous blocks and isolate concurrency.
Maintainer #
Jank Scout is created and maintained by Muhammad Omar.
License #
This project is licensed under the MIT License. See the LICENSE file for details.