You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redux React多Action分发缓慢问题技术咨询

Hey there, let's break down each of your questions about Redux dispatch performance in development mode, and share some actionable tips to speed things up!

1. Why does each dispatch take ~300ms, and what does that time include?

That 300ms in development absolutely covers the full chain of a Redux dispatch:

  • Calling the action creator (your action1() is a simple sync function, so this part is nearly instant)
  • The thunk middleware passing the action through (since your actions are plain objects, thunk just forwards them immediately)
  • Running the reducer to generate a new state (your setIn call here is part of this step)
  • Redux notifying all subscribers (like React-Redux's connect components) that the state has changed
  • Critical for dev mode: Extra checks and logging from Redux devtools, immutable state validation (if you're using middleware like redux-immutable-state-invariant), and React's strict mode double-invocation of lifecycles/reducers.

Most of that 300ms is likely coming from those dev-only tools and checks, not the core action/reducer logic—your production build proves this, since those overheads are stripped out.

2. Why am I waiting for each dispatch to finish even with redux-thunk? Isn't thunk supposed to run in parallel?

Great question! Redux-thunk lets you write async action creators, but your action1-action5 are all sync: they return plain action objects, not functions. Thunk only does special handling when you return a function (e.g., for API calls). For plain objects, thunk just passes them directly to store.dispatch()—which is a synchronous operation.

Redux state updates are always sync by design: when you call dispatch, it runs the reducer, updates the state, and notifies subscribers immediately before moving to the next line of code. Even if you don't see visible re-renders, Redux still has to process the state change, notify all subscribers, and let devtools record the update—all of which blocks the event loop until it's done.

To run dispatches in parallel, you'd need to wrap them in async functions (like setTimeout or Promise.all) so they don't block each other, but keep in mind that Redux will still process each state update one at a time under the hood (since state updates are atomic).

3. Does having a large amount of data in my Store affect performance?

Absolutely—this is probably a major contributor to your dev-mode slowdown. Here's why:

  • Immutable checks: Dev-mode middleware like redux-immutable-state-invariant recursively scans your entire state tree to make sure you didn't mutate it directly. A large state means this scan takes way longer.
  • Devtools serialization: Redux devtools needs to serialize your entire state to display it in the browser. Big state = more time spent converting to JSON and storing history.
  • Subscriber updates: Even if your components don't re-render, connect components still run their mapStateToProps functions to compare old/new props. A large state can make these comparisons slower, especially if you're selecting large chunks of state without memoization.

4. Is 300ms per dispatch normal?

In development mode, with a large state and default dev tooling, it's possible—but it's definitely slower than ideal. Your production build's 0-2ms times are what you should expect for core Redux logic. The 300ms is almost entirely dev-mode overhead that we can optimize.


Tips to Speed Up Dev-Mode Dispatch Performance

  • Trim dev middleware: Disable redux-immutable-state-invariant if you're confident in your immutable updates, or configure it to only check specific branches of your state instead of the whole tree.
  • Optimize Redux DevTools: Tweak the devtools config to reduce overhead:
    const store = createStore(
      rootReducer,
      window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__({
        maxAge: 5, // Limit how many state history entries are stored
        shouldRecordChanges: false, // Disable auto-recording if you don't need it
        serialize: { options: { ignore: ['largeNestedData'] } } // Skip serializing huge state parts
      })
    )
    
  • Fix reducer immutability: Wait, you mentioned using a "mutable lodash version of set" in your reducer? Redux requires reducers to be pure functions that return new state, not mutate the existing one. If you're using lodash.set (which mutates the original state object), that's a problem—it will trigger immutable checks to fail and cause unexpected behavior. Switch to immutable update patterns: use Immer (which lets you write "mutating" code that converts to immutable updates), or use spread operators/Object.assign.
  • Memoize selectors: Use reselect to create memoized mapStateToProps selectors, so they only recalculate when the specific state slice they care about changes. This reduces unnecessary computations during state updates.
  • Delay non-critical dispatches: If some of these actions don't need to run immediately on mount, wrap them in setTimeout(() => {}, 0) to let the browser finish rendering first before processing the dispatch.

内容的提问来源于stack exchange,提问作者Waltari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:42:40