Flutter Daily - Isolates for Heavy Computation
Isolates for Heavy Computation
What You’ll Learn
Dart runs on a single thread by default, which means heavy computations can freeze your UI. Isolates let you run code in separate threads, keeping your app smooth and responsive even during intensive tasks like parsing large JSON files or processing images.
The Problem: UI Blocking
When you run heavy computations on the main thread, Flutter can’t render frames, causing your app to freeze:
// BAD: This will freeze the UI
void processLargeData() {
// Simulating heavy computation
for (int i = 0; i < 1000000000; i++) {
// Complex calculation
}
}
The Solution: Isolates
Isolates are Dart’s way of achieving true parallelism. Each isolate has its own memory and event loop:
import 'dart:isolate';
// Function that runs in separate isolate
Future<int> heavyComputation(int value) async {
return await Isolate.run(() {
// This runs on a separate thread
int result = 0;
for (int i = 0; i < value; i++) {
result += i;
}
return result;
});
}
// Usage in your widget
class ComputationDemo extends StatefulWidget {
@override
State<ComputationDemo> createState() => _ComputationDemoState();
}
class _ComputationDemoState extends State<ComputationDemo> {
int? result;
bool isLoading = false;
Future<void> runComputation() async {
setState(() => isLoading = true);
// UI stays responsive during this
final value = await heavyComputation(100000000);
setState(() {
result = value;
isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
ElevatedButton(
onPressed: runComputation,
child: Text('Run Heavy Computation'),
),
if (isLoading) CircularProgressIndicator(),
if (result != null) Text('Result: $result'),
],
);
}
}
Real-World Example: JSON Parsing
Here’s a practical example parsing large JSON data:
import 'dart:convert';
import 'dart:isolate';
// Parse JSON in isolate
Future<List<User>> parseUsersInIsolate(String jsonString) async {
return await Isolate.run(() {
final List<dynamic> jsonList = jsonDecode(jsonString);
return jsonList.map((json) => User.fromJson(json)).toList();
});
}
// Your model
class User {
final String name;
final String email;
User({required this.name, required this.email});
factory User.fromJson(Map<String, dynamic> json) {
return User(name: json['name'], email: json['email']);
}
}
Try It Yourself
- Create a Flutter app with a button that runs a heavy computation using
Isolate.run() - Add an animation (like a rotating circle) to verify the UI stays smooth during computation
- Compare it with the same computation running on the main thread - notice the difference!
Bonus challenge: Use compute() helper function (from Flutter foundation library) which is a simpler wrapper around isolates:
import 'package:flutter/foundation.dart';
final result = await compute(heavyFunction, inputData);
Tip of the Day
When to use isolates:
- Parsing large JSON (> 100KB)
- Image processing or compression
- Encryption/decryption
- Complex calculations
When NOT to use isolates:
- Simple, fast operations (isolate overhead isn’t worth it)
- Operations requiring access to Flutter framework objects (isolates can’t share memory)
Debugging tip: Isolates can’t be debugged with breakpoints in the same way. Use print() statements or logging to debug code running in isolates.