pmndrs / zustand

🐻 Bear necessities for state management in React

Home Page:https://zustand-demo.pmnd.rs/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

When the set operation is executed in the 「then callback」, the 「set operation」 takes nearly a hundred times longer.

LZY622 opened this issue · comments

When the set operation is executed in the 「then callback」, the「set operation」 takes nearly a hundred times longer.

In a new umi framework,Add a button to the page and add a handle to the button to test the time consumption of the 「set operation」.

Print time-consuming code(Store)

import {create} from "zustand";
export const useStore = create<any>()((set, get) => ({
  loading: false, 
  setLoading: (loading: boolean) => {
    console.time('time--set')
    set({ loading })
    console.timeEnd('time--set')
  },
}))

UI code

return (
  <div>
    <div>{String(loading)}</div>
    <Button type="primary" onClick={testSetHandle}>setLoading</Button>
  </div>
);

Experiment 1

Handle code:

const testSetHandle = useCallback(async () => {
  setLoading(!loading)
}, [loading])

Time consuming printing:
set0

Experiment 2

Handle code:

const testSetHandle = useCallback(async () => {
  await sleep(3000);
  console.log('sleep 3000')
  setLoading(!loading)
}, [loading])

Time consuming printing:
set1

Experiment 3

Handle code:

const testSetHandle = useCallback(async () => {
  await sleep(3000);
  console.log('sleep 3000')
  await sleep(2000);
  console.log('sleep 2000')
  setLoading(!loading)
}, [loading])

Time consuming printing:
set2

Experiment 4

Handle code:

const testSetHandle = useCallback(async () => {
  await sleep(3000);
  console.log('sleep 3000')
  await sleep(2000);
  console.log('sleep 2000')
  await sleep(1000);
  console.log('sleep 1000')
  setLoading(!loading)
}, [loading])

Time consuming printing:
set3

Experiment 5

Handle code:

const testSetHandle = useCallback(async () => {
  await sleep(3000);
  console.log('sleep 3000')
  await sleep(2000);
  console.log('sleep 2000')
  await sleep(1000);
  console.log('sleep 1000')
  await sleep(2000);
  console.log('sleep 2000')
  setLoading(!loading)
}, [loading])

Time consuming printing:
set4

Conclusions and conjectures

If there is an await statement before the set operation, the set operation will take longer. And the more awaits, the more time it takes. From experiments, we can find that there seems to be a threshold for the number of awaits. In the example, if there are more than 2 awaits, the time consumption will jump directly to 30ms.In our actual project, due to factors such as store size, a simple set operation will take 200+ms. The essence of await is the syntactic sugar of 「.then callback」, so it is reasonable to speculate that it is related to the number of nesting of 「.then」.Please suggest some solutions, thank you very much

Link to reproduction

The code is relatively simple to reproduce,code repository is no longer provided

Check List

Please do not ask questions in issues.

  • I've already opened a discussion before opening this issue, or already discussed in other media.

Please include a minimal reproduction.

Please check this if you're filing an issue regarding TypeScript.

  • I've read the typescript guide, in particular that create is to be used as create<T>()(...) and not create<T>(...).