Flutterで効率よく非同期処理をやるにはどうすべきか(※未検証)
最近はいろんなプロジェクトに顔を突っ込みつつ課題解決をする仕事をしています。
その中で、FlutterでAPI通信やDBアクセスなど時間のかかる処理をUIの描画と合わせてどううまくやるのか考えています。
ネイティブ実装ではどうやるか
iOSであればDispachQueue、Androidであればcoroutineを使うことで、UIを描画するメインスレッドとデータ操作をする別スレッドを分けることが一般的になっています。
Flutter(Dart)はシングルスレッドで動く
一方でFlutterはNode.jsと同様に、基本DartがMain Isolateのシングルスレッドで動くようです。Future / Streamを使って非同期処理は記述できますが、イベントループになります。
JavaScriptの例にはなりますが、イベントループについてはこちらの資料がわかりやすかったです。
Isolateを複数立てれば並列処理ができる
DartではMain Isolateとは別のIsolateを立てることで並列処理ができるようになるようです。
詳しくはmonoさんの以下の記事が詳しいですが、isolateのスイッチングにオーバーヘッドがあるそうです。
また先日のFlutterKaigiでもKurogoma4DさんからIsolateに関する解説がありました。
質疑応答で、isolateを使うのとMethodChannelでDispachQueueやCoroutineを使うのとどっちが性能がでるかふと気になったのですが、実際に試してみないと分からなそうです。
Isolateで非同期処理やるのとMethodChannelで各OS側で非同期処理やるのどっちが性能いいのか気になっている。なんとなくIsolateのほうが遅そうな印象。 #FlutterKaigi
— takamii228 (@takamii228) 2021年11月30日
非同期処理をFlutterでやるか、ネイティブでやるか?
Flutterでアーキテクチャを考えるときにネイティブ実装との境目をどこに持つのかは一つの大きな関心毎です。
なるべくFlutter側に寄せればDartの割合が増えるので書くコード量は減りますが、その分Flutter(Dart)への依存度が増えるのでFlutter(Dart)の動作仕様の影響を受けます。この動作仕様のデメリットをネイティブ実装で補えるのか否かが気になりますね。
今度時間があるときに検証しようと思います(おい)
あと並列処理と並行処理もちゃんと区別せねば...。