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

NGRX Store带负载Action导致HTTP内容加载性能持续劣化求助

Performance Degradation & Crash When Dispatching NGRX Actions with HTTP Payloads

I've run into a critical performance issue with NGRX in my Angular app: dispatching Actions that carry HTTP response payloads leads to steadily increasing HTTP request latency, eventually causing the app to crash.

Here's the breakdown of what I've observed and tested:

  • The app uses ngrx/entity and works fine for most features, but the problem occurs specifically in a scenario where we're fetching data on a timed loop and dispatching two Actions afterward.
  • Both custom test functions and Chrome DevTools' waterfall view confirm that the GET request phase is the biggest bottleneck. However, the server itself isn't the issue—when running the same HTTP requests outside of the Store/Action pipeline, they consistently finish in under 300ms.
  • Control tests reveal the root cause is tied to Action payloads:
    • Dispatching a dummy Action with no payload performs just as well as a raw HTTP request.
    • Dispatching a dummy Action with the full HTTP response payload (even with no corresponding Reducer to handle it) still causes performance degradation—though to a slightly lesser degree.
  • My working hypothesis is that the synchronous nature of Action dispatch is blocking the main thread, especially with large payloads, leading to cumulative request queueing over time.

Relevant Effect Code

@Effect() 
getAllClusterInfo: Observable<Action> = this.actions$
  .ofType<actions.GetAllClusterInfoObjectsAction>(actions.GET_ALL_CLUSTER_INFO_OBJECTS)
  .do(_ => console.log(_))
  .switchMap(() => {
    const str = `Info: ${Math.round(Math.random() * 10000)}`;
    console.time('Full ' + str)
    console.time('Get ' + str)
    return this.service$.getAllClusterInfoObjects()
      .do(_ => console.timeEnd('Get ' + str))
      .map(info => new actions.GetAllClusterInfoObjectsSuccessAction(info))
      .do(_ => console.timeEnd('Full ' + str))
      .catch(err => of(new actions.GetAllClusterInfoObjectsFailAction(err)));
  });

Troubleshooting & Fix Recommendations

1. Audit Payload Size

First, check how much data getAllClusterInfoObjects() is returning. Large datasets can choke the main thread during Action dispatch, even if no Reducer modifies the Store. Use Chrome DevTools' Performance tab to record a session—look for long tasks during the Action dispatch phase.

  • Fixes: Implement server-side pagination to reduce payload size per request, or have the server return only the fields your frontend actually needs (trim redundant data).

2. Reduce Unnecessary Store Subscriptions

Even without a matching Reducer, dispatching an Action triggers notifications to all Store subscribers. If you have dozens of components subscribed to the Store, each dispatch will trigger a round of change detection—this adds up quickly in a timed loop.

  • Fixes:
    • Use select with projection to let components only subscribe to the slice of state they need.
    • Add distinctUntilChanged to your selectors to filter out redundant updates that don't affect the component's view.

3. Decouple Action Dispatch from Main Thread

Since synchronous dispatch is likely blocking the main thread, try pushing the Action dispatch to a microtask to free up the thread for HTTP processing:

.map(info => {
  // Push Action dispatch to microtask queue
  return Promise.resolve(new actions.GetAllClusterInfoObjectsSuccessAction(info));
})
.mergeMap(promise => promise)

This is a quick test to validate your hypothesis—if latency improves, you can explore cleaner ways to handle async dispatch (though NGRX generally expects Actions to be synchronous, this workaround can help isolate the issue).

4. Upgrade NGRX & Check for Known Issues

Older versions of NGRX had performance bottlenecks around Action dispatch and Store notifications. If you're on an older version (pre-v14), upgrading to the latest stable release might resolve the issue out of the box.

5. Optimize Action Creation

If you're using manual Action classes, switch to NGRX's createAction utility with props<T>(). This generates more efficient Action creators that avoid unnecessary object copying, which can help with large payloads.

内容的提问来源于stack exchange,提问作者L.P.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:30:32