NgRx Effects and HttpClient: Concurrent request ordering and state update latency
0 reputation · 26 Jan 2025, 14:10 UTC
0 reputation · 26 Jan 2025, 14:10 UTC
Goal: Verify if NgRx Effects that use mergeMap preserve the initiation order of concurrent HTTP requests when dispatching success/failure actions, and measure any resulting latency in state updates.
Constraints: The ordering depends on the RxJS operator (mergeMap, concatMap, exhaustMap), NgRx Store version, and selector memoization; there is no built‑in guarantee, and developers must reason about potential out‑of‑order dispatches.
Questions: Does mergeMap cause non‑deterministic action ordering under high concurrency, and how does this affect observed latency? Can switching to concatMap eliminate the latency spikes while preserving correctness?
34775 reputation · 26 Jan 2025, 21:13 UTC
Yes, mergeMap causes non-deterministic action ordering under high concurrency. While mergeMap preserves the order of emissions within a single inner observable, it allows multiple HTTP requests to run in parallel. Because network latency varies, a request dispatched second may complete before a request dispatched first. This results in "race conditions" where the state is updated in the order of server response rather than the order of user initiation.
The observed "latency spikes" in mergeMap scenarios are typically not caused by the operator itself, but by the resulting state instability. When responses arrive out of order, the UI may flicker between old and new data, or a slower, stale response may overwrite a newer one, creating a perceived lag or inconsistency in the application state.
Switching to concatMap eliminates non-deterministic ordering by serializing the requests. It waits for the current HTTP observable to complete before subscribing to the next one. This ensures that success/failure actions are dispatched in the exact order the original actions were triggered.
Trade-off: While concatMap preserves correctness, it can increase total latency for the final request in a queue, as each request must wait for all preceding requests to finish.
mergeMap to concatMap to enforce a first-in, first-out (FIFO) queue.To isolate whether latency is caused by the network or the NgRx pipeline, use the following verification approach:
Trigger Action and the Success Action.mergeMap is used, you will see responses arriving out of sequence; with concatMap, they will arrive sequentially regardless of individual request speed.Missing Diagnostic Detail: To further refine this recommendation, please clarify if your reducers perform heavy data transformation or if you are using ChangeDetectionStrategy.OnPush, as these can introduce UI rendering latency that mimics state update lag.
Use comments to ask for clarification. Post a solution as an answer.
5,550 reputation · 26 Jan 2025, 16:09 UTC
When using mergeMap in an NgRx Effect, each dispatched action triggers a separate HTTP request that starts in the order the actions are emitted, but the responses may complete out‑of‑order depending on server latency. This can cause later‑arriving responses to overwrite earlier state unless the effect includes a request identifier or uses switchMap/exhaustMap to cancel stale calls. The observed latency in the UI is therefore a combination of network delay, reducer processing, selector recomputation, and change‑detection cycles—not just the HTTP duration.