flutter-concurrency

$npx mdskill add HoangNguyen0403/agent-skills-standard/flutter-concurrency

Dart uses a single-threaded event loop. All Flutter code runs on the Main Isolate by default. Blocking it causes jank.

SKILL.md

.github/skills/flutter-concurrencyView on GitHub ↗
---
name: flutter-concurrency
description: Execute long-running tasks in background isolates to keep the UI responsive. Use when performing heavy computations, parsing large datasets, or choosing between async/await and isolates.
metadata:
  triggers:
    files:
    - '**/*isolate*.dart'
    - '**/*worker*.dart'
    keywords:
    - Isolate
    - compute
    - Isolate.run
    - Isolate.spawn
    - ReceivePort
    - SendPort
    - background
---
# Dart Concurrency and Isolates

## **Priority: P1**

## Core Concepts

Dart uses a single-threaded event loop. All Flutter code runs on the Main Isolate by default. Blocking it causes jank.

- **async/await**: For non-blocking I/O (network, file). The event loop continues while waiting.
- **Isolates**: Dart's lightweight threads with isolated memory. Communicate via message passing only.

## Decision Matrix

| Condition | Approach |
|-----------|----------|
| I/O bound (HTTP, database) | `async`/`await` on Main Isolate |
| CPU-bound, < 16ms | `async`/`await` on Main Isolate |
| CPU-bound, one-off heavy task | `Isolate.run()` |
| Continuous background processing | `Isolate.spawn()` with ports |

## Workflow: Offloading Heavy Computation

- [ ] 1. Identify the CPU-bound operation blocking the UI.
- [ ] 2. Extract computation into a standalone top-level or static function.
- [ ] 3. Ensure the function accepts exactly one argument (Isolate constraint).
- [ ] 4. Call `Isolate.run(() => myFunction(data))`.
- [ ] 5. `await` the result on the Main Isolate.

## Workflow: Long-Lived Worker Isolate

- [ ] 1. Create a `ReceivePort` on the Main Isolate.
- [ ] 2. Spawn worker with `Isolate.spawn(entryPoint, mainPort.sendPort)`.
- [ ] 3. In worker, create its own `ReceivePort` and send its `SendPort` back.
- [ ] 4. Store worker's `SendPort` for bidirectional communication.
- [ ] 5. Close ports and kill isolate on dispose.

See [examples](references/isolate-examples.md) for complete code.

## Anti-Patterns

- **No JSON parsing on Main Isolate**: Large JSON decoding (>1MB) blocks frames. Use `Isolate.run`.
- **No shared mutable state**: Isolates cannot share memory. Pass data via messages.
- **No FutureBuilder in build without caching**: `FutureBuilder` re-fires on every rebuild if the future is created inline.

## Verification

- [ ] No frame drops during heavy computation (check with DevTools).
- [ ] Worker isolates are disposed when no longer needed.
- [ ] `flutter test` passes.

## References

- [Isolate Examples](references/isolate-examples.md)

More from HoangNguyen0403/agent-skills-standard

SkillDescription
android-agp-upgradeUpgrade an Android project to Android Gradle Plugin (AGP) 9. Use when migrating to AGP 9, updating Gradle build files, migrating to built-in Kotlin, or adopting the new AGP DSL.
android-architectureApply Clean Architecture layering, modularization, and Unidirectional Data Flow in Android projects. Use when setting up project structure, placing code in layers, configuring feature/core modules, or implementing UDF patterns.
android-background-workImplement WorkManager and background processing correctly on Android. Use when creating Worker classes, scheduling tasks, choosing between WorkManager and Foreground Services, or setting up Hilt in workers.
android-composeBuild high-performance declarative UI with Jetpack Compose. Use when writing Composable functions, optimizing recomposition, hoisting state, or working with LazyColumn and side effects.
android-compose-migrationMigrate an Android XML View to Jetpack Compose following a structured 10-step workflow. Use when converting XML layouts to Compose, setting up Compose in an existing View-based project, or incrementally adopting Compose.
android-concurrencyWrite correct coroutine scopes, Flow collection, and dispatcher injection in Android. Use when writing suspend functions, choosing between StateFlow and SharedFlow, or injecting Dispatchers for testability.
android-deploymentConfigure release signing, R8 obfuscation, and App Bundle publishing for Android. Use when setting up signing configs, enabling minification, adding ProGuard keep rules, or preparing for Play Store submission.
android-design-systemEnforce Material Design 3 theming and design token usage in Jetpack Compose. Use when implementing M3 components, color schemes, typography, or design tokens.
android-diConfigure Hilt dependency injection with proper scoping, modules, and constructor injection in Android. Use when setting up Hilt DI, defining modules, or configuring component scoping.
android-edge-to-edgeMigrate a Jetpack Compose app to edge-to-edge display and fix system bar inset issues. Use when UI components are obscured by navigation/status bars, fixing IME insets, or enabling edge-to-edge for SDK 35+.