Skip to content

Commands isolate

albertoodev edited this page Jul 31, 2026 · 7 revisions

isolate: targeted profiling

isolate extracts rebuild scopes such as a Flutter State class or a BlocBuilder callback into standalone Dart files. The smaller files make it possible to profile one UI segment without running the rest of the application.

Usage

spm isolate --output-dir ./isolated_widgets /path/to/project
spm isolate -o ./isolation-output -j map.jsonl /path/to/project

Options and flags

Flag / Option Short Description
--output-dir <path> -o Required. Directory where the isolated files are saved.
--jsonl <path> -j Output JSONL mapping original source paths → isolated file paths.
--verbose -v Enable verbose logging of the isolation process.
<dir> [dir…] One or more directories to scan for rebuild scopes.

How it works

Isolation combines static analysis with source transformation.

1. Discovery

An AST visitor scans the target directories for rebuild boundaries:

  • Classes that extend State, ConsumerWidget, or HookConsumerWidget.
  • Anonymous builder functions passed to BlocBuilder, BlocSelector, BlocConsumer, Consumer, Selector, Obx, GetX, GetBuilder, or Observer.

2. Normalization and transplantation

The TransplantExtractor converts a discovered scope into a new, self-contained StatefulWidget (GeneratedWidget).

  • For a State class, SPM also finds its companion StatefulWidget to extract fields and constructors.
  • For a builder function, SPM extracts parameters such as state or model and converts them into fields on the new state.

3. Transitive dependency resolution

To keep the generated file compilable, SPM recursively crawls the code for every referenced symbol:

  • Methods, fields, and getters used within the same class or file move into the generated file.
  • A custom widget, enum, or painter from another file is extracted along with its own dependencies.
  • Business logic, models, and services are left out; the generated target may need mocks or values supplied by the benchmark harness.
  • Required package:flutter and dart: imports are collected automatically.

4. Visual transformation (skeletonization)

Isolated widgets often lack the original project's assets. The Skeletonizer:

  • Identifies widgets like Image.network, AssetImage, or SvgPicture.
  • Replaces them with lightweight placeholders.
  • Keeps missing image files from preventing layout and rendering.

Output structure

output/
├── State/
│   ├── login_form_state.dart
│   └── product_list_state.dart
├── BlocBuilder/
│   └── user_profile_builder.dart
└── mapping.jsonl

Mapping file (mapping.jsonl)

Links each isolated file back to its original source. One JSON object per line:

{
  "originalPath": "/abs/path/to/project/lib/ui/login_form.dart",
  "nodeType": "State",
  "isolatedPath": "/abs/path/to/output/State/login_form_state.dart",
  "name": "LoginFormState"
}
Field Description
originalPath Absolute path of the source file the scope was extracted from.
nodeType Scope kind, which is also the output subdirectory name (State, BlocBuilder, Consumer, …).
isolatedPath Absolute path of the generated standalone file.
name Name of the extracted class or builder-owning widget.

When isolation fits

Use an isolated scope when a whole application adds unrelated work to frame timings or when a benchmark needs direct control of the values passed into one builder. The generated GeneratedWidget can be placed in a benchmark loop and supplied with controlled inputs.

Limitations

  • Because SPM skips non-UI dependencies, code involving complex models or services may need manual adjustment or mocking in the generated file.
  • The Skeletonizer handles images, but custom fonts or localized strings may still need manual setup if critical to the widget.

Clone this wiki locally