Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Choose a side-effect library for MapStore #1420

Closed
offtherailz opened this issue Feb 3, 2017 · 1 comment
Closed

Choose a side-effect library for MapStore #1420

offtherailz opened this issue Feb 3, 2017 · 1 comment

Comments

@offtherailz
Copy link
Member

offtherailz commented Feb 3, 2017

Motivation

We have complex async operations and side-effects, that are very difficult to be realized in thunk. In addition we want to trigger some side effects, and the way we did it (with componentReceiveProps) is hard to understand, maintain, and also an anti-pattern.

Lens

We want :

  • the components without logic (pure rendering)
  • the actions as pure functions
  • avoid callback hell (promises are good for this only with 1 value ajax call)
  • complex ajax calls (maybe all, for the future) in a more readable
  • support task cancellation
  • Throttling, De-bouncing, parallel and serial groups of async task should be simple

Candidates

Candidates are:

both of them have a middleware to integrate in redux, that catch actions and can produce other actions.

redux-observable

redux-observable realizes it using epics. Epics are functions that get and return observables (see rxjs ).
This observable (that are streams ) receive actions and produce actions. The saga defines the stream to create composing, merging, forking and producing actions from the original events.
Look like a lodash for async.

redux-sagas

Uses ES6 generator functions to represent the sequences of async calls. You may think to them like infinite loop (and without using helper they are while(true) loops) threads listening to the actions produced by redux.

Comparison

I developed the same functionality (text search with multiple services, with some hard-codings) in mapstore 2 to put them on test:
redux-observable
redux-saga

Usage

redux-saga is the most used (see this
redux-saga is 6 months old, while saga is out born 1 year and a half ago, and side effect management was a must for not trivial projects. This explains why it is so used.

BoilerPlate Code

The boilerplate code is very similar. with the following differences:

  • sagas need babel-polyfill
  • observable need to require rxjs in when used. Include all or only the needed functionalities.

Learning Curve

  • Learn redux-observables means mainly learn rxjs. It is useful for other project in the future. Developers with this knowledges will find it super simple.

  • Learn redux-sagas requires to learn how generator work, and even if you may not need to know how binding with redux is done, some of the lines of code you write will not be clear without studying it.

Problem Solving

(Solving common problems like throttling, de-bouncing, multiple parallel requests and cancellation)

  • Seems hard with sagas. Thinking the how the sequence continue and what is the current state of it may be very hard. But the sequence seems most straight forward. during the spike, some problems seems unsolved
  • Seems simpler with sagas. (rxjs AKA lodash for async) You don't see the sequence as you see with sagas, but any doubt can be solved drawing marple diagrams

Coding speed

  • Sagas seem harder to write, but may be only a first-impression
  • After learning main observable methods, epics seem very easy and quick to write.

Code clean

  • Sagas are more linear, but not so easy to understand as you can imagine.
  • Epics look functional, maybe something is not clear to a newbie of observables, but when you learn the most common operations with observables, everything becomes more clear.

Testing

  • sagas: should be super-simple. When you test them, basically you test that the sequence of actions is correct, that is pretty trivial, but also not so useful.
  • epics: need a mock store (redux-mock-store) to bind. Then you can verify that the store dispatch the some actions in consequence of the ones you trigger.

Size of the libs

Rxjs is a big sized library. We should be able to reduce it including only the needed functionalities :

redux-observable: 7.57 KB (0.0501%)
rxjs: 640.88 KB (4.24%)

while sagas is lighter:

redux-saga: 65.58 KB (0.451%)
babel-polyfill: 1001 B (0.00673%)

Performances

Rxjs 4 had good performances (with good hardware and without node at scale). Rxjs5 improved performances first with results like the following source :

  • 5x faster on average in V8 (not our purpose)
  • 3x faster in common scenarios on resource constrained devices (600Mhz ARM, low RAM)
  • Most common libs ~10x faster execution.
    So performances should be good in any condition, right now, with redux-observable.

redux-saga: didn't found any information about performances tests, some issues solved.

Summary

Sagas Epics Notes
Usage X x* * rxjs is used widely
Boiler Plate X X
Learning Curve X X
Problem Solving X
Coding Speed X X
Code Clean x* X * most of the problems are hidden
Testing x* X * I think is not useful testing sagas the way they test
Size of the libs X
Performances X X
@offtherailz offtherailz added this to the 2017.02.00 milestone Feb 3, 2017
@MV88
Copy link
Contributor

MV88 commented Feb 7, 2017

After the brain washing made by @offtherailz I would vote for Observable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants