eaglesakuraの技術ブログ

技術的な話題とか、メモとか。

Flutter + Redux Architectureでパフォーマンスチューニング

パフォーマンスチューニングが必要になった理由

  • プロジェクトでRedux Architectureを採用したが、求める機能に合致するライブラリがないためチーム内で自作した pub.dev
  • これにより求める機能が実装されたが、プロジェクトでは特定条件下でState更新が1000回 / 秒を超える場合がある
  • UI = f(State)を愚直に実装していたため、Widget.build()が1000回 / 秒走ることとなり、パフォーマンスに明らかな悪影響が出た

解決方法

  • Stateを流すためのStreamと、WidgetをビルドするためのStreamを分けた
  • StateをハンドリングするためのStreamは取りこぼしがあってはならない(イベントハンドリングなど)ため、実装をそのままとした
  • それとは別に、WidgetをビルドするためのStreamを追加した
    • こちらは最大で60fpsでデータが流れる仕様となっているため、仮に1000回 / 秒State更新が走ってもWidgetに反映されるのは60回 / 秒が最大である
  /// レンダリング用に流通量を制限したStreamを生成する.
  BehaviorSubject<TState> _initializeRenderStream(Duration renderingInterval) {
    final result = BehaviorSubject<TState>.seeded(state);
    _subscription.add(
      Stream.periodic(
        renderingInterval,
        (computationCount) => state,
      ).distinct().listen(result.add),
    );
    return result;
  }
  • これによりWidget.build()のスパイクによる異常rebuildを回避してパフォーマンスが向上した