Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid synchronously adding setState callbacks #3743

Merged
merged 5 commits into from Sep 29, 2022
Merged

Conversation

JoviDeCroock
Copy link
Member

@JoviDeCroock JoviDeCroock commented Sep 22, 2022

Fixes #3742

The issue in question is caused by our mutable _renderCallbacks and the timing of which we push our new state-setting callback into it.

In the test-scenario we have a component that mounts without children due to a loading state variable being true, imagine a spinner or something instead here.
After our component mounts we set this variable to false effectively mounting our child-component which has a componentDidMount of itself which calls a setState on the parent, due to this setState we will synchronously push our setState callback onto the _renderCallbacks which is the one from the render we are still processing.

Now why do we call it with componentDidUpdate and not without? Well we push a _renderCallback when we are updating from loading true to false which puts this parent component into the renderQueue which we consume in the inverse order of the tree (child --> parent) this leads us to calling the setState callback when the intermediary render completes (read not the one where we update the parent state).

To solve this we ensure that we only push this callback when we are consuming the render coupled to this dirty state by means of adding a _stateCallbacks mechanism that is consumed when the component is handled.

@JoviDeCroock JoviDeCroock marked this pull request as draft September 22, 2022 09:47
@github-actions
Copy link

github-actions bot commented Sep 22, 2022

📊 Tachometer Benchmark Results

Summary

duration

  • 02_replace1k: unsure 🔍 -5% - +2% (-8.50ms - +2.79ms)
    preact-local vs preact-master
  • 03_update10th1k_x16: unsure 🔍 -4% - +3% (-1.30ms - +0.97ms)
    preact-local vs preact-master
  • 07_create10k: unsure 🔍 -2% - +1% (-30.19ms - +11.20ms)
    preact-local vs preact-master
  • filter_list: faster ✔ 1% - 5% (0.23ms - 1.07ms)
    preact-local vs preact-master
  • hydrate1k: unsure 🔍 -3% - +3% (-4.57ms - +4.69ms)
    preact-local vs preact-master
  • many_updates: unsure 🔍 -4% - +4% (-1.82ms - +1.78ms)
    preact-local vs preact-master
  • text_update: unsure 🔍 -1% - +6% (-0.03ms - +0.18ms)
    preact-local vs preact-master
  • todo: unsure 🔍 -1% - +2% (-0.47ms - +1.36ms)
    preact-local vs preact-master

usedJSHeapSize

  • 02_replace1k: unsure 🔍 -2% - +4% (-0.07ms - +0.16ms)
    preact-local vs preact-master
  • 03_update10th1k_x16: unsure 🔍 -1% - +0% (-0.02ms - +0.01ms)
    preact-local vs preact-master
  • 07_create10k: slower ❌ 1% - 1% (0.16ms - 0.16ms)
    preact-local vs preact-master
  • filter_list: slower ❌ 1% - 2% (0.03ms - 0.03ms)
    preact-local vs preact-master
  • hydrate1k: unsure 🔍 -2% - +2% (-0.16ms - +0.12ms)
    preact-local vs preact-master
  • many_updates: unsure 🔍 +0% - +0% (+0.00ms - +0.00ms)
    preact-local vs preact-master
  • text_update: unsure 🔍 +0% - +0% (+0.00ms - +0.00ms)
    preact-local vs preact-master
  • todo: unsure 🔍 -1% - +1% (-0.02ms - +0.01ms)
    preact-local vs preact-master

Results

02_replace1k

duration

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master151.29ms - 157.78ms-unsure 🔍
-2% - +6%
-2.79ms - +8.50ms
unsure 🔍
-4% - +6%
-6.15ms - +8.41ms
preact-local147.05ms - 156.30msunsure 🔍
-5% - +2%
-8.50ms - +2.79ms
-unsure 🔍
-6% - +4%
-9.71ms - +6.26ms
preact-hooks146.89ms - 159.92msunsure 🔍
-5% - +4%
-8.41ms - +6.15ms
unsure 🔍
-4% - +6%
-6.26ms - +9.71ms
-

usedJSHeapSize

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master3.68ms - 3.82ms-unsure 🔍
-4% - +2%
-0.16ms - +0.07ms
faster ✔
8% - 15%
0.34ms - 0.63ms
preact-local3.70ms - 3.90msunsure 🔍
-2% - +4%
-0.07ms - +0.16ms
-faster ✔
7% - 14%
0.28ms - 0.60ms
preact-hooks4.11ms - 4.37msslower ❌
9% - 17%
0.34ms - 0.63ms
slower ❌
7% - 16%
0.28ms - 0.60ms
-

run-warmup-0

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master1.25ms - 1.32ms-unsure 🔍
-9% - +1%
-0.12ms - +0.02ms
faster ✔
4% - 15%
0.05ms - 0.21ms
preact-local1.28ms - 1.40msunsure 🔍
-1% - +10%
-0.02ms - +0.12ms
-unsure 🔍
-12% - +1%
-0.17ms - +0.02ms
preact-hooks1.34ms - 1.49msslower ❌
3% - 17%
0.05ms - 0.21ms
unsure 🔍
-2% - +13%
-0.02ms - +0.17ms
-

run-warmup-1

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master0.74ms - 0.97ms-unsure 🔍
-27% - +20%
-0.24ms - +0.18ms
slower ❌
8% - 50%
0.06ms - 0.32ms
preact-local0.71ms - 1.07msunsure 🔍
-21% - +29%
-0.18ms - +0.24ms
-slower ❌
4% - 64%
0.04ms - 0.42ms
preact-hooks0.60ms - 0.73msfaster ✔
10% - 35%
0.06ms - 0.32ms
faster ✔
9% - 42%
0.04ms - 0.42ms
-

run-warmup-2

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master0.82ms - 1.05ms-unsure 🔍
-2% - +32%
-0.01ms - +0.26ms
slower ❌
7% - 48%
0.07ms - 0.34ms
preact-local0.75ms - 0.88msunsure 🔍
-26% - -0%
-0.26ms - +0.01ms
-unsure 🔍
-3% - +25%
-0.02ms - +0.18ms
preact-hooks0.66ms - 0.80msfaster ✔
9% - 34%
0.07ms - 0.34ms
unsure 🔍
-22% - +1%
-0.18ms - +0.02ms
-

run-warmup-3

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master0.40ms - 0.48ms-unsure 🔍
-15% - +9%
-0.07ms - +0.04ms
faster ✔
9% - 25%
0.04ms - 0.14ms
preact-local0.42ms - 0.50msunsure 🔍
-9% - +16%
-0.04ms - +0.07ms
-faster ✔
6% - 22%
0.03ms - 0.12ms
preact-hooks0.51ms - 0.56msslower ❌
8% - 32%
0.04ms - 0.14ms
slower ❌
5% - 27%
0.03ms - 0.12ms
-

run-warmup-4

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master2.47ms - 5.25ms-unsure 🔍
-60% - +7%
-3.45ms - +0.65ms
slower ❌
10% - 437%
1.13ms - 4.20ms
preact-local3.75ms - 6.77msunsure 🔍
-26% - +99%
-0.65ms - +3.45ms
-slower ❌
66% - 616%
2.42ms - 5.71ms
preact-hooks0.53ms - 1.85msfaster ✔
49% - 89%
1.13ms - 4.20ms
faster ✔
63% - 91%
2.42ms - 5.71ms
-

run-final

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master0.27ms - 0.34ms-unsure 🔍
-40% - +1%
-0.16ms - +0.02ms
unsure 🔍
-14% - +18%
-0.04ms - +0.05ms
preact-local0.29ms - 0.46msunsure 🔍
-7% - +55%
-0.02ms - +0.16ms
-unsure 🔍
-4% - +57%
-0.01ms - +0.17ms
preact-hooks0.27ms - 0.33msunsure 🔍
-17% - +14%
-0.05ms - +0.04ms
unsure 🔍
-40% - -2%
-0.17ms - +0.01ms
-
03_update10th1k_x16

duration

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master33.29ms - 34.86ms-unsure 🔍
-3% - +4%
-0.97ms - +1.30ms
slower ❌
1% - 7%
0.38ms - 2.39ms
preact-local33.09ms - 34.73msunsure 🔍
-4% - +3%
-1.30ms - +0.97ms
-slower ❌
1% - 7%
0.19ms - 2.25ms
preact-hooks32.06ms - 33.32msfaster ✔
1% - 7%
0.38ms - 2.39ms
faster ✔
1% - 7%
0.19ms - 2.25ms
-

usedJSHeapSize

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master3.74ms - 3.76ms-unsure 🔍
-0% - +1%
-0.01ms - +0.02ms
faster ✔
8% - 9%
0.33ms - 0.36ms
preact-local3.73ms - 3.76msunsure 🔍
-1% - +0%
-0.02ms - +0.01ms
-faster ✔
8% - 9%
0.33ms - 0.37ms
preact-hooks4.08ms - 4.11msslower ❌
9% - 10%
0.33ms - 0.36ms
slower ❌
9% - 10%
0.33ms - 0.37ms
-
07_create10k

duration

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master1524.62ms - 1555.92ms-unsure 🔍
-1% - +2%
-11.20ms - +30.19ms
faster ✔
1% - 4%
19.12ms - 62.93ms
preact-local1517.24ms - 1544.32msunsure 🔍
-2% - +1%
-30.19ms - +11.20ms
-faster ✔
2% - 4%
30.07ms - 70.96ms
preact-hooks1565.97ms - 1596.62msslower ❌
1% - 4%
19.12ms - 62.93ms
slower ❌
2% - 5%
30.07ms - 70.96ms
-

usedJSHeapSize

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master25.52ms - 25.52ms-faster ✔
1% - 1%
0.16ms - 0.16ms
faster ✔
10% - 10%
2.71ms - 2.71ms
preact-local25.68ms - 25.69msslower ❌
1% - 1%
0.16ms - 0.16ms
-faster ✔
9% - 9%
2.55ms - 2.55ms
preact-hooks28.23ms - 28.23msslower ❌
11% - 11%
2.71ms - 2.71ms
slower ❌
10% - 10%
2.55ms - 2.55ms
-
filter_list

duration

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master22.65ms - 23.32ms-slower ❌
1% - 5%
0.23ms - 1.07ms
unsure 🔍
-1% - +2%
-0.30ms - +0.53ms
preact-local22.08ms - 22.58msfaster ✔
1% - 5%
0.23ms - 1.07ms
-faster ✔
1% - 4%
0.19ms - 0.88ms
preact-hooks22.63ms - 23.11msunsure 🔍
-2% - +1%
-0.53ms - +0.30ms
slower ❌
1% - 4%
0.19ms - 0.88ms
-

usedJSHeapSize

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master1.75ms - 1.75ms-faster ✔
1% - 2%
0.03ms - 0.03ms
faster ✔
14% - 15%
0.28ms - 0.32ms
preact-local1.78ms - 1.78msslower ❌
1% - 2%
0.03ms - 0.03ms
-faster ✔
13% - 14%
0.26ms - 0.29ms
preact-hooks2.03ms - 2.07msslower ❌
16% - 18%
0.28ms - 0.32ms
slower ❌
14% - 16%
0.26ms - 0.29ms
-
hydrate1k

duration

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master153.49ms - 159.31ms-unsure 🔍
-3% - +3%
-4.69ms - +4.57ms
unsure 🔍
-5% - +1%
-7.28ms - +1.06ms
preact-local152.86ms - 160.06msunsure 🔍
-3% - +3%
-4.57ms - +4.69ms
-unsure 🔍
-5% - +1%
-7.74ms - +1.63ms
preact-hooks156.52ms - 162.50msunsure 🔍
-1% - +5%
-1.06ms - +7.28ms
unsure 🔍
-1% - +5%
-1.63ms - +7.74ms
-

usedJSHeapSize

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master6.31ms - 6.55ms-unsure 🔍
-2% - +2%
-0.12ms - +0.16ms
faster ✔
7% - 13%
0.45ms - 0.90ms
preact-local6.34ms - 6.48msunsure 🔍
-2% - +2%
-0.16ms - +0.12ms
-faster ✔
7% - 12%
0.49ms - 0.90ms
preact-hooks6.92ms - 7.30msslower ❌
7% - 14%
0.45ms - 0.90ms
slower ❌
8% - 14%
0.49ms - 0.90ms
-
many_updates

duration

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master44.08ms - 46.71ms-unsure 🔍
-4% - +4%
-1.78ms - +1.82ms
faster ✔
6% - 13%
2.71ms - 6.65ms
preact-local44.15ms - 46.61msunsure 🔍
-4% - +4%
-1.82ms - +1.78ms
-faster ✔
6% - 13%
2.78ms - 6.61ms
preact-hooks48.61ms - 51.54msslower ❌
6% - 15%
2.71ms - 6.65ms
slower ❌
6% - 15%
2.78ms - 6.61ms
-

usedJSHeapSize

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master4.81ms - 4.82ms-unsure 🔍
-0% - -0%
-0.00ms - -0.00ms
faster ✔
9% - 9%
0.45ms - 0.45ms
preact-local4.82ms - 4.82msunsure 🔍
+0% - +0%
+0.00ms - +0.00ms
-faster ✔
8% - 9%
0.45ms - 0.45ms
preact-hooks5.26ms - 5.26msslower ❌
9% - 9%
0.45ms - 0.45ms
slower ❌
9% - 9%
0.45ms - 0.45ms
-
text_update

duration

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master2.98ms - 3.02ms-unsure 🔍
-6% - +1%
-0.18ms - +0.03ms
faster ✔
9% - 10%
0.29ms - 0.34ms
preact-local2.98ms - 3.18msunsure 🔍
-1% - +6%
-0.03ms - +0.18ms
-faster ✔
4% - 10%
0.13ms - 0.34ms
preact-hooks3.30ms - 3.33msslower ❌
10% - 11%
0.29ms - 0.34ms
slower ❌
4% - 11%
0.13ms - 0.34ms
-

usedJSHeapSize

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master0.98ms - 0.98ms-unsure 🔍
-0% - -0%
-0.00ms - -0.00ms
faster ✔
2% - 2%
0.02ms - 0.02ms
preact-local0.99ms - 0.99msunsure 🔍
+0% - +0%
+0.00ms - +0.00ms
-faster ✔
1% - 1%
0.01ms - 0.01ms
preact-hooks1.00ms - 1.00msslower ❌
2% - 2%
0.02ms - 0.02ms
slower ❌
2% - 2%
0.01ms - 0.01ms
-
todo

duration

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master63.22ms - 64.44ms-unsure 🔍
-2% - +1%
-1.36ms - +0.47ms
faster ✔
3% - 6%
2.19ms - 4.09ms
preact-local63.59ms - 64.95msunsure 🔍
-1% - +2%
-0.47ms - +1.36ms
-faster ✔
3% - 5%
1.70ms - 3.70ms
preact-hooks66.24ms - 67.70msslower ❌
3% - 6%
2.19ms - 4.09ms
slower ❌
3% - 6%
1.70ms - 3.70ms
-

usedJSHeapSize

VersionAvg timevs preact-mastervs preact-localvs preact-hooks
preact-master1.38ms - 1.40ms-unsure 🔍
-1% - +1%
-0.01ms - +0.02ms
slower ❌
1% - 4%
0.01ms - 0.05ms
preact-local1.37ms - 1.39msunsure 🔍
-1% - +1%
-0.02ms - +0.01ms
-slower ❌
0% - 4%
0.01ms - 0.05ms
preact-hooks1.34ms - 1.37msfaster ✔
1% - 4%
0.01ms - 0.05ms
faster ✔
0% - 3%
0.01ms - 0.05ms
-

tachometer-reporter-action v2 for Benchmarks

@github-actions
Copy link

github-actions bot commented Sep 22, 2022

Size Change: +190 B (0%)

Total Size: 53.1 kB

Filename Size Change
dist/preact.js 4.05 kB +30 B (0%)
dist/preact.min.js 4.08 kB +31 B (0%)
dist/preact.min.module.js 4.08 kB +32 B (0%)
dist/preact.min.umd.js 4.11 kB +30 B (0%)
dist/preact.module.js 4.08 kB +35 B (0%)
dist/preact.umd.js 4.12 kB +32 B (0%)
ℹ️ View Unchanged
Filename Size Change
compat/dist/compat.js 3.78 kB 0 B
compat/dist/compat.module.js 3.72 kB 0 B
compat/dist/compat.umd.js 3.85 kB 0 B
debug/dist/debug.js 3.01 kB 0 B
debug/dist/debug.module.js 3.01 kB 0 B
debug/dist/debug.umd.js 3.09 kB 0 B
devtools/dist/devtools.js 231 B 0 B
devtools/dist/devtools.module.js 239 B 0 B
devtools/dist/devtools.umd.js 314 B 0 B
hooks/dist/hooks.js 1.56 kB 0 B
hooks/dist/hooks.module.js 1.59 kB 0 B
hooks/dist/hooks.umd.js 1.64 kB 0 B
jsx-runtime/dist/jsxRuntime.js 358 B 0 B
jsx-runtime/dist/jsxRuntime.module.js 324 B 0 B
jsx-runtime/dist/jsxRuntime.umd.js 439 B 0 B
test-utils/dist/testUtils.js 442 B 0 B
test-utils/dist/testUtils.module.js 444 B 0 B
test-utils/dist/testUtils.umd.js 526 B 0 B

compressed-size-action

@JoviDeCroock JoviDeCroock marked this pull request as ready for review September 22, 2022 11:09
@JoviDeCroock JoviDeCroock changed the title create test case for #3742 Avoid synchronously adding setState callbacks Sep 22, 2022
Copy link
Member

@marvinhagemeister marvinhagemeister left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Impressed with how quickly you found a solution 🙌

@coveralls
Copy link

coveralls commented Sep 22, 2022

Coverage Status

Coverage increased (+0.002%) to 99.529% when pulling da77efe on set-state-cb into dfd45aa on master.

Copy link

@zjhch123 zjhch123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for your quick fix!

@developit
Copy link
Member

I'd like a bit of time to noodle on size for this one if we can. Performance numbers look good though.

@JoviDeCroock JoviDeCroock merged commit d30a0ed into master Sep 29, 2022
@JoviDeCroock JoviDeCroock deleted the set-state-cb branch September 29, 2022 08:33
JoviDeCroock added a commit that referenced this pull request Oct 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

componentDidUpdate affects component state
5 participants