Home > Mobile >  Redux dispatch action takes more time with a big store
Redux dispatch action takes more time with a big store

Time:01-01

I have created a simple example that shows that the bigger store you have the more time you need to dispatch an empty action.

Is it really true that dispatch timing depend on store size?

Here is the example CodeSandbox

With an empty store when I try to dispatch a simple action like

dispatch({ type: "hey" });

it takes less than 1ms.

But with a store that contains 100 000 strings it takes about 10 ms. And as matter of fact more strings you have - more time it takes.

I used to think the dispatch does not depend on store size but now I have to rethink my approach. If store contains a lot of data it could happen that every dispatch will take seconds.

Does really dispatch timing depend on store size?

Image

Here is my code:

const dispatch = useAppDispatch();

const [log, setLog] = useState<Array<string>>([]);
const add = (text: string) => {
  setLog([...log, text]);
};

const loadData = async () => {
  add("loading a lot of data to the redux store");

  const newState = [];
  let i;
  for (i = 0; i < 100000; i  ) {
    newState.push(i.toString());
  }

  dispatch({ type: "project", payload: { project: newState } });
  add(`data loaded: ${i} strings`);
};

const dummy = async () => {
  add("start dummy dispatch");
  const t0 = performance.now();
  dispatch({ type: "hey" });
  const t1 = performance.now();
  add(`Time it takes to run the function: ${t1 - t0} ms`);
};

const clear = async () => {
  dispatch({ type: "project", payload: { project: [] } });
  setLog([]);
};

return (
  <>
    <div>
      <button onClick={loadData}>Load data</button>
      <button onClick={dummy}>Dispatch empty action</button>
      <button onClick={clear}>Clear</button>
    </div>
    {log.map((l, i) => {
      return <div key={i}>{l}</div>;
    })}
  </>
);

store.ts

import { combineReducers } from "redux";
import {configureStore} from "@reduxjs/toolkit";
import {useDispatch} from "react-redux";
import getProjectReducer from "./reducers/project";

const reducers = combineReducers({
  Project: getProjectReducer
})

export const store = configureStore({
  reducer: reducers,
  devTools: process.env.NODE_ENV !== "production",
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat()
});

export type RootState = ReturnType<typeof store.getState>;

export type AppDispatch = typeof store.dispatch;

export const useAppDispatch = () => useDispatch<AppDispatch>();

export default store

reducer

import { createReducer, PayloadAction } from '@reduxjs/toolkit';

const getProjectReducer = createReducer<{project: Array<any>}>({project: []}, {
  'project': (
    state,
    action: PayloadAction<{
      project: any;
    }>
  ) => {
    const {project} = action.payload
    state.project=project;
    return state;
  },
});

export default getProjectReducer;

CodePudding user response:

What you're seeing is Redux Toolkit's development-build-only check for non-serializable values in actions and state. Iterating over the contents of the action and state does take time, and so a larger action or state object will take longer to scan.

However, that check does not run in production.

As a side note, you really should be using Redux Toolkit's createSlice API rather than calling createReducer directly, as createSlice is simpler to use (and actually calls createReducer internally).

  • Related