Skip to content

[v8] useSelector without custom subscription manager is slower than v7 (performance regression) #1869

Closed
@Kasdy

Description

@Kasdy

What version of React, ReactDOM/React Native, Redux, and React Redux are you using?

  • React: 18.0.0-rc0
  • ReactDOM: 18.0.0-rc0
  • Redux: 4.1.2
  • React Redux: 8.0.0-beta2

What is the current behavior?

In React-Redux v8 the custom Subscription manager was removed from useSelector,
and store.subscribe from Redux is used directly in useSyncExternalStore call.

This will bring back a performance problem (#1450), because Redux unsubscription relies on indexOf\splice.

React 18 + React-Redux v8.0.0
Screenshot 2022-02-05 01 36 43

React 17 + React-Redux v7.2.6
Screenshot 2022-02-05 01 24 30

Test code:

const store = createStore(
    (state = 0, action) => (action.type === "INC" ? state + 1 : state)
);
const increment = () => ({ type: "INC" });

function App() {
    const state = useSelector(s => s);
    const dispatch = useDispatch();

    const [children, setChildren] = useState(0);

    const toggleChildren = () => setChildren(c => c ? 0 : 50000);

    return <div>
        <button onClick={toggleChildren}>Toggle Children</button>
        <button onClick={() => dispatch(increment())}>Increment</button>
        {[...Array(children).keys()].map(i => <Child key={i}/>)}
    </div>;

}

function Child() {
    const v = useSelector(s => s);
    return <div className="child">{v}</div>;
}

What is the expected behavior?

The Subscription manager used in v7 has better performance than Redux unsubscription used in v8 with many listeners.
It's still in the bundle, because <Provider> uses it, so it could be used again in useSelector too.

Which browser and OS are affected by this issue?

No response

Did this work in previous versions of React Redux?

  • Yes

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions