Swift ConcurrencyにおけるTaskPriorityの重要性
はじめに
こんにちは。
iOSエンジニアの長です。
WealthNaviアプリ内の実装で、TaskPriority
を省略してしまった結果、
想定外の問題が発生し、無事解消できたので共有します。
何が起きたのか
特定の端末でアプリの起動に非常に時間がかかるという現象が観測されました。
その端末は数年前に発売された端末であり、
単純に端末の処理性能不足が原因であると推測していました。
より詳細に調査を進めた結果、特定の時期に修正した処理が原因であることがわかりました。
RxSwiftからSwift Councurrencyへの移行中ということもあり、上記の修正時点で個別に TaskPriority
を定義していませんでした。
何が原因だったのか
記事タイトルにもある通り、Swift Concurrencyの TaskPriority
= 優先度 を適切に設定していないことが原因でした。
タスクの優先度を指定しない場合、親タスクの優先度を引き継ぐことになります。
Child tasks automatically inherit their parent task’s priority.
タスク優先度を指定せず複数のタスクを実行すると、親タスクの優先度を引き継いだ複数のタスクが同時に存在することになります。
このような状況に陥ると、端末によってはタスクをうまく処理することができず、スタックしてしまいます。
下図は、解析ツールであるInstrumentsを利用して タスクの処理状況を時系列で可視化したものです。
上図の赤枠部分に注目すると、タスクを中断する部分(灰色、緑色)、タスクを実行する部分(青色)が断片化しておりタスクがほとんど実行されていないことがわかります。
どうやって解決したか
タスク生成時に TaskPriority
を明示しました。
- Task {
+ Task(priority: .background) {
先述のボトルネックとなっていたタスクは、アプリ利用に直接影響のないタスクであり、
タスクの優先度をbackground
(優先度最低)まで下げました。
優先度を下げた後のタスクの処理状況を以下に示します。
タスク実行の断片化が解消され、タスク実行がスムーズに行われていることがわかります。
まとめ
TaskPriority
を明示的に設定することで、タスクの実行エラーを解消できました。
また、この対応によりアプリの起動時間も大幅に短縮されました。
最近の端末は処理性能が高く、このような問題は起こりにくいものの、古い端末をサポートする必要があるアプリケーションの参考になれば幸いです。
さらに、タスクごとに適切な優先度を設定することでアプリの操作性が向上する可能性もあるため、TaskPriority
の見直しをお勧めします。
Discussion