Question #184EasyDart BasicsImportant

What is isolates ?

#dart

Answer

Overview

Isolates are Dart's concurrency mechanism -- each isolate is an independent worker with its own memory heap. Unlike threads in other languages, isolates cannot share memory; they communicate only via message passing.


Why Isolates?

Dart's main thread runs the UI at 60fps. CPU-heavy operations (parsing large JSON, image processing, encryption) block the UI thread and cause jank. Isolates solve this by offloading work.

text
Main Isolate (UI Thread)    Background Isolate
-- Widget rendering         -- Parses 50MB JSON
-- Animations               -- Processes images
-- User events              -- Encrypts files
-- 'Send me the result'     -- 'Here is your result'
            Message Passing

Simple Isolate with compute()

Flutter provides

text
compute()
-- the easiest way to run code in a background isolate:

dart
import 'package:flutter/foundation.dart';

// Top-level or static function (required for isolates)
List<int> heavyComputation(List<int> numbers) {
  return numbers.map((n) => n * n).toList(); // CPU intensive
}

// In widget
Future<void> _process() async {
  final result = await compute(heavyComputation, [1, 2, 3, 4, 5]);
  print(result); // [1, 4, 9, 16, 25]
  setState(() => _data = result);
}

Isolate.run() (Dart 2.19+)

dart
import 'dart:isolate';

// Simple background task
final result = await Isolate.run(() {
  // Runs in background isolate
  return parseHeavyJson(rawData);
});

Manual Isolate with SendPort/ReceivePort

dart
import 'dart:isolate';

void isolateWorker(SendPort sendPort) {
  // Works in background
  final result = expensiveCalculation();
  sendPort.send(result); // Send result to main isolate
}

Future<void> runHeavyTask() async {
  final receivePort = ReceivePort();

  // Spawn isolate
  await Isolate.spawn(isolateWorker, receivePort.sendPort);

  // Wait for result
  final result = await receivePort.first;
  print('Result: $result');
  receivePort.close();
}

Two-Way Communication

dart
Future<void> twoWayExample() async {
  final receivePort = ReceivePort();
  await Isolate.spawn(echoIsolate, receivePort.sendPort);

  final sendPort = await receivePort.first as SendPort;

  // Send data to isolate
  final responsePort = ReceivePort();
  sendPort.send({'data': 'hello', 'replyPort': responsePort.sendPort});

  final response = await responsePort.first;
  print('Response: $response');
}

void echoIsolate(SendPort sendPort) {
  final port = ReceivePort();
  sendPort.send(port.sendPort);

  port.listen((message) {
    final msg = message as Map;
    final replyPort = msg['replyPort'] as SendPort;
    replyPort.send('Echo: ${msg['data']}');
  });
}

When to Use Isolates

TaskIsolate?
Parse large JSON (>1MB)Yes
Image/video processingYes
Encryption/hashingYes
Database queries (Hive, Isar)Yes -- built-in isolate support
Regular API callsNo -- async is enough
setState, UI updatesNo -- main isolate only

Key Rule: Isolates cannot share memory. All data passed between them must be copyable (primitives, lists, maps). UI updates must happen on the main isolate via

text
setState()
after receiving the result.