Skip to content

0.0.12

Choose a tag to compare

@github-actions github-actions released this 25 Aug 13:03
· 22 commits to master since this release
908be36

Added

  • dusk:perf_begin / dusk:perf_end: frame attribution around a driven interaction. A dusk session could tell you a screen was slow and nothing about why. The pair brackets an interaction: perf_begin turns FlutterTimeline collection on (first, because startSync and finishSync both read that flag and enabling the build flags ahead of it pushes a finish with no matching start), then debugProfileBuildsEnabled + debugProfileBuildsEnabledUserWidgets, and on --phases also debugProfileLayoutsEnabled + debugProfilePaintsEnabled. The flags live in two different libraries, package:flutter/widgets.dart and package:flutter/rendering.dart. perf_end returns the frame summary under Flutter's own metric names, a session-wide block ranking naming the widget and RenderObject types that ran, wind's cache hit/miss/bypass counters and magic's controller-notify counts, then puts every flag back to the value it had BEFORE the session rather than to false, because a host that had build profiling on for its own reasons must get it back. A perf_begin on an already-open session restarts it, restoring before it re-saves, so a dropped connection cannot strand the profiling flags on. New: lib/src/extensions/ext_perf.dart, lib/src/commands/dusk_perf_begin_command.dart, lib/src/commands/dusk_perf_end_command.dart, plus the dusk_perf_begin / dusk_perf_end MCP descriptors. 36 CLI commands, 35 MCP tools, 32 ext.dusk.* extensions.

  • A session the engine did not render through is refused, not reported. Every number in a stalled session is a zero, and a table of zeros reads as "fast": that is the reading a live probe produced three times against a Chrome tab that was merely behind another window. perf_end compares a liveness counter across the session and answers refused: true with a reason and NO metrics block at all when it did not advance. The counter is the authority rather than the warnings block on the same response: SchedulerBinding.framesEnabled, which that block reads, was measured reporting true with lifecycle resumed on a page that was hidden and had produced one frame in two seconds. Both signals can ride on one payload, so refused is always present and is the only discriminator. dusk:perf_end exits non-zero on a refusal so a shell caller cannot chain on a report that does not exist.

  • Four settable perf pointers on the public barrel, and a frame summarizer behind them. dusk's frozen contract #10 limits it to four dependencies and telescope, wind and magic are none of them, so the data crosses through function pointers magic_devtools assigns: framePerfReader (frames plus the liveness counter), perfExtrasReader (magic's controller notifies and route transitions), perfSessionBeginHook (zero wind's counters AND turn its counting on; WindPerfCounters.enabled defaults to false and dusk cannot reach it, so a hook that only zeroed would have produced a wind section of all zeros next to fully populated frame and magic sections with no error anywhere) and perfSessionEndHook (turn it back off, the same discipline perf_end applies to the debugProfile* flags). All four default to no-ops, so dusk and magic_devtools build independently. summarizeFramePerf in lib/src/utils/frame_summary.dart (package-internal, deliberately not on the barrel) turns the frame list into average_frame_build_time_millis, the 90th/99th percentiles, the worst frame, the missed-budget counts and the rasterizer equivalents, using flutter_driver's metric-name strings character for character so a reading here is comparable to devicelab's. Two additions Flutter's own summarizer has no counterpart for: a dropped-frame count derived from GAPS in the frame-number sequence, because on web a dropped scene is a missing frame number rather than a slow frame, and the worst N frames with their block attribution attached. New: lib/src/utils/perf_readers.dart, lib/src/utils/frame_summary.dart; the four pointers are exported from lib/dusk.dart and listed under ARCHITECTURE.md's frozen contracts.

  • Per-type durations are labelled indicative in the payload itself. Flutter's docblocks on the three debugProfile* flags say the overhead of adding timeline events is significant relative to the time each object takes, and this session runs against a debug build, which widens the gap again. A number that travels without that caveat gets quoted as a production fact, so perf_end carries a note saying it: the counts, the ratios and the ranking are what direct a fix.