diff --git a/src/devTools.js b/src/devTools.js index 4704438a..fa079486 100644 --- a/src/devTools.js +++ b/src/devTools.js @@ -95,6 +95,7 @@ function liftReducer(reducer, initialState) { * Manages how the DevTools actions modify the DevTools state. */ return function liftedReducer(liftedState = initialLiftedState, liftedAction) { + let shouldRecomputeStates = true; let { committedState, stagedActions, @@ -131,6 +132,8 @@ function liftReducer(reducer, initialState) { break; case ActionTypes.JUMP_TO_STATE: currentStateIndex = liftedAction.index; + // Optimization: we know the history has not changed. + shouldRecomputeStates = false; break; case ActionTypes.SWEEP: stagedActions = stagedActions.filter((_, i) => !skippedActions[i]); @@ -142,8 +145,21 @@ function liftReducer(reducer, initialState) { if (currentStateIndex === stagedActions.length - 1) { currentStateIndex++; } + stagedActions = [...stagedActions, liftedAction.action]; 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; case ActionTypes.SET_MONITOR_STATE: monitorState = liftedAction.monitorState; @@ -159,12 +175,14 @@ function liftReducer(reducer, initialState) { break; } - computedStates = recomputeStates( - reducer, - committedState, - stagedActions, - skippedActions - ); + if (shouldRecomputeStates) { + computedStates = recomputeStates( + reducer, + committedState, + stagedActions, + skippedActions + ); + } return { committedState,