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.