mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2024-11-25 19:13:56 +03:00
Merge pull request #133 from gaearon/optimize-state-computation
Do not recompute states unless necessary
This commit is contained in:
commit
32371664a0
|
@ -95,6 +95,7 @@ function liftReducer(reducer, initialState) {
|
||||||
* Manages how the DevTools actions modify the DevTools state.
|
* Manages how the DevTools actions modify the DevTools state.
|
||||||
*/
|
*/
|
||||||
return function liftedReducer(liftedState = initialLiftedState, liftedAction) {
|
return function liftedReducer(liftedState = initialLiftedState, liftedAction) {
|
||||||
|
let shouldRecomputeStates = true;
|
||||||
let {
|
let {
|
||||||
committedState,
|
committedState,
|
||||||
stagedActions,
|
stagedActions,
|
||||||
|
@ -131,6 +132,8 @@ function liftReducer(reducer, initialState) {
|
||||||
break;
|
break;
|
||||||
case ActionTypes.JUMP_TO_STATE:
|
case ActionTypes.JUMP_TO_STATE:
|
||||||
currentStateIndex = liftedAction.index;
|
currentStateIndex = liftedAction.index;
|
||||||
|
// Optimization: we know the history has not changed.
|
||||||
|
shouldRecomputeStates = false;
|
||||||
break;
|
break;
|
||||||
case ActionTypes.SWEEP:
|
case ActionTypes.SWEEP:
|
||||||
stagedActions = stagedActions.filter((_, i) => !skippedActions[i]);
|
stagedActions = stagedActions.filter((_, i) => !skippedActions[i]);
|
||||||
|
@ -142,8 +145,21 @@ function liftReducer(reducer, initialState) {
|
||||||
if (currentStateIndex === stagedActions.length - 1) {
|
if (currentStateIndex === stagedActions.length - 1) {
|
||||||
currentStateIndex++;
|
currentStateIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
stagedActions = [...stagedActions, liftedAction.action];
|
stagedActions = [...stagedActions, liftedAction.action];
|
||||||
timestamps = [...timestamps, liftedAction.timestamp];
|
timestamps = [...timestamps, liftedAction.timestamp];
|
||||||
|
|
||||||
|
// Optimization: we know that the past has not changed.
|
||||||
|
shouldRecomputeStates = false;
|
||||||
|
// Instead of recomputing the states, append the next one.
|
||||||
|
const previousEntry = computedStates[computedStates.length - 1];
|
||||||
|
const nextEntry = computeNextEntry(
|
||||||
|
reducer,
|
||||||
|
liftedAction.action,
|
||||||
|
previousEntry.state,
|
||||||
|
previousEntry.error
|
||||||
|
);
|
||||||
|
computedStates = [...computedStates, nextEntry];
|
||||||
break;
|
break;
|
||||||
case ActionTypes.SET_MONITOR_STATE:
|
case ActionTypes.SET_MONITOR_STATE:
|
||||||
monitorState = liftedAction.monitorState;
|
monitorState = liftedAction.monitorState;
|
||||||
|
@ -159,12 +175,14 @@ function liftReducer(reducer, initialState) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shouldRecomputeStates) {
|
||||||
computedStates = recomputeStates(
|
computedStates = recomputeStates(
|
||||||
reducer,
|
reducer,
|
||||||
committedState,
|
committedState,
|
||||||
stagedActions,
|
stagedActions,
|
||||||
skippedActions
|
skippedActions
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
committedState,
|
committedState,
|
||||||
|
|
|
@ -212,4 +212,35 @@ describe('devTools', () => {
|
||||||
storeWithBug.dispatch({ type: 'SET_UNDEFINED' });
|
storeWithBug.dispatch({ type: 'SET_UNDEFINED' });
|
||||||
expect(storeWithBug.getState()).toBe(2);
|
expect(storeWithBug.getState()).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not recompute states on every action', () => {
|
||||||
|
let reducerCalls = 0;
|
||||||
|
let monitoredStore = devTools()(createStore)(() => reducerCalls++);
|
||||||
|
expect(reducerCalls).toBe(1);
|
||||||
|
monitoredStore.dispatch({ type: 'INCREMENT' });
|
||||||
|
monitoredStore.dispatch({ type: 'INCREMENT' });
|
||||||
|
monitoredStore.dispatch({ type: 'INCREMENT' });
|
||||||
|
expect(reducerCalls).toBe(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not recompute states when jumping to state', () => {
|
||||||
|
let reducerCalls = 0;
|
||||||
|
let monitoredStore = devTools()(createStore)(() => reducerCalls++);
|
||||||
|
let monitoredDevToolsStore = monitoredStore.devToolsStore;
|
||||||
|
|
||||||
|
expect(reducerCalls).toBe(1);
|
||||||
|
monitoredStore.dispatch({ type: 'INCREMENT' });
|
||||||
|
monitoredStore.dispatch({ type: 'INCREMENT' });
|
||||||
|
monitoredStore.dispatch({ type: 'INCREMENT' });
|
||||||
|
expect(reducerCalls).toBe(4);
|
||||||
|
|
||||||
|
monitoredDevToolsStore.dispatch(ActionCreators.jumpToState(0));
|
||||||
|
expect(reducerCalls).toBe(4);
|
||||||
|
|
||||||
|
monitoredDevToolsStore.dispatch(ActionCreators.jumpToState(1));
|
||||||
|
expect(reducerCalls).toBe(4);
|
||||||
|
|
||||||
|
monitoredDevToolsStore.dispatch(ActionCreators.jumpToState(3));
|
||||||
|
expect(reducerCalls).toBe(4);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user