Performance Optimization of Flutter Applications Using Fish Redux
By analyzing severe UI lag in a Flutter retail app, the team discovered that Fish Redux’s refresh mechanism and an inefficient JSON key‑conversion library caused excessive rebuilds; rewriting shouldUpdate, adopting ImmutableConn, and replacing Recase with a cached converter cut lag by roughly 60 % and demonstrated the importance of fine‑grained component management for high‑performance Flutter applications.
Introduction: Flutter is a mainstream cross‑platform mobile technology; Fish Redux is a state‑management framework used in many retail mobile apps.
Problem background: Users reported severe UI lag on cash register devices when adding/modifying items, loading data, or navigating screens. The lag manifested in slow button response, janky animations, and sluggish list scrolling.
Root‑cause analysis: The issues were divided into two categories – time‑consuming data loading and UI rendering lag. Using DevTools performance view, the team identified heavy rebuilds caused by Fish Redux’s refresh mechanism and an inefficient JSON key conversion library (Recase).
Fish Redux architecture overview: Fish Redux follows a Redux‑style pattern with State, Effect, Reducer and Action. Components are built from Component, ComponentWidget and ComponentState. Only components that implement a Reducer can trigger self‑refresh; otherwise they inherit updates from parent components.
abstract class Component
extends Logic
implements AbstractComponent
{ /* ... */ }The refresh flow involves ComponentContext registering Effect receivers and store listeners, and the store dispatching actions to reducers.
class ComponentState
extends State
> { void initState() { _ctx.registerOnDisposed(widget.store.subscribe(() => _ctx.onNotify())); } }Connector mechanism: MutableConn clones parent state on child updates, leading to whole‑page rebuilds; ImmutableConn updates only the sub‑state reference.
SubReducer
subReducer(Reducer
reducer) { return (T state, Action action, bool isStateCopied) { final P newProps = reducer(props, action); final bool hasChanged = !identical(newProps, props); if (hasChanged) { final T result = set(state, newProps); return result; } return state; }; }Solutions:
Rewrite shouldUpdate to return false for pure container components, preventing unnecessary whole‑tree rebuilds.
Use ImmutableConn where parent components do not need to react to child state changes.
Replace the costly Recase library with a custom, cached key‑conversion implementation.
class ReCase { final RegExp _upperAlphaRegex = RegExp(r'[A-Z]'); List
_groupIntoWords(String text) { StringBuffer sb = StringBuffer(); /* conversion logic */ return words; } }Result: After applying the above optimizations, UI lag was reduced by about 60%, and the application no longer exhibited noticeable stutters.
Conclusion: Understanding Fish Redux’s refresh mechanism and carefully managing component granularity are essential for high‑performance Flutter apps.
Youzan Coder
Official Youzan tech channel, delivering technical insights and occasional daily updates from the Youzan tech team.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.