During app setup, static reducers are created and initialized. The way that happens is - first Store/Index/configureStore is called to initialize the store’s injectReducer method and then Store/Index/injectStaticReducers is called to inject all static reducers in a loop.
The problem is that, when called in a loop, injectReducer is combining and replacing all of the already set-up reducers with each new reducer. This is a very expensive operation and it can be improved by splitting the loop into two parts - first, set up all reducers and then, combine them all at once.
The issue usually is noticeable by a long App component’s mount time. Especially when the app is using a lot of static reducers. When looking at the network requests this may appear as a gap between render chunk download and FCP. This is especially apparent when there is a 4x CPU slowdown applied
By looking into the performance tab in the browser, it can be seen that the combineReducers function is taking a lot of time when the App component is being mounted.

InjectReducers method here takes ~ 190ms
Store/Index/configureStore/**
* Configure the store
* @namespace Store/Index/configureStore
* */
export function configureStore(store) {
// Add a dictionary to keep track of the registered async reducers
store.asyncReducers = {};
// Create an inject reducer function
// This function adds the async reducer, and creates a new combined reducer
store.injectReducer = (key, asyncReducer) => {
store.asyncReducers[key] = asyncReducer;
};
store.combineReducers = () => {
store.replaceReducer(combineReducers(store.asyncReducers));
};
// Return the modified store
return store;
}
In the code, snippet can be seen that configureStore is now returning the store with two methods - injectReducer and combineReducers. The first one is used to add a new reducer to the store and the second one is used to combine all reducers into one.
configureStore usageSince Store/Index/getStore is using it in the same file, need to also overwrite it so that the correct configureStore gets called.
injectReducerStore/Index/injectStaticReducersexport default function injectStaticReducers(store) {
// eslint-disable-next-line no-param-reassign
store.asyncReducers = [];
// Inject all the static reducers into the store
Object.entries(getStaticReducers()).forEach(
([name, reducer]) => {
// eslint-disable-next-line no-param-reassign
store.asyncReducers[name] = reducer;
store.injectReducer(name, reducer);
}
);
store.combineReducers();
return store;
}
Util/DynamicReducers/Helper/injectToReducersexport default function injectToReducers(store, reducers) {
Object.keys(reducers).forEach((key) => {
if (!Reflect.has(store.asyncReducers, key)) {
// eslint-disable-next-line no-param-reassign
store.asyncReducers[key] = reducers[key];
store.injectReducer(key, reducers[key]);
}
});
store.combineReducers();
}
injectReducerThis is project specific, so need to search for where else could store.injectReducer is used, and add combineReducers similar to before.
Verify with the performance tab that the time of configureStore has been reduced

Here can see that combineReducers is called only once and whole configureStore takes ~3x less time to process.