Skip to content

Ensure we reset renderCount#5017

Merged
JoviDeCroock merged 3 commits intov10.xfrom
remove-act-leak-in-core
Feb 26, 2026
Merged

Ensure we reset renderCount#5017
JoviDeCroock merged 3 commits intov10.xfrom
remove-act-leak-in-core

Conversation

@JoviDeCroock
Copy link
Member

@JoviDeCroock JoviDeCroock commented Feb 10, 2026

Currently due to the condition of prevDebounce != options.debounceRendering we leak an implementation detail of act in our general implementation. We don't want this so we're just exposing process on options to avoid us having to account for this in the future. When our consumers override options.debounceRendering they might accidentally introduce more renders than intended when is about to be processed.

The above did not work out, we should encourage people to override options.debounceRendering before scheduling any preact updates which should entirely bypass the possiblity of this

Another issue we had was that if process() would throw without any resolution in the component tree that process._rerenderCount would never return back to 0 and hence stop any future render from being scheduled. This is handled in the try finally block.

I've also added a byte saving opportunity with pushing the component._dirty check down a bit.

Resolves #5002

@github-actions
Copy link

github-actions bot commented Feb 10, 2026

📊 Tachometer Benchmark Results

Summary

duration

  • create10k: unsure 🔍 -0% - +1% (-4.46ms - +5.66ms)
    preact-local vs preact-main
  • filter-list: unsure 🔍 -1% - +2% (-0.16ms - +0.27ms)
    preact-local vs preact-main
  • hydrate1k: unsure 🔍 -1% - +2% (-0.48ms - +1.32ms)
    preact-local vs preact-main
  • many-updates: unsure 🔍 -0% - +0% (-0.06ms - +0.07ms)
    preact-local vs preact-main
  • replace1k: unsure 🔍 -2% - +1% (-1.11ms - +0.85ms)
    preact-local vs preact-main
  • text-update: unsure 🔍 -5% - +2% (-0.10ms - +0.03ms)
    preact-local vs preact-main
  • todo: unsure 🔍 -0% - +1% (-0.11ms - +0.34ms)
    preact-local vs preact-main
  • update10th1k: unsure 🔍 -4% - +4% (-1.32ms - +1.24ms)
    preact-local vs preact-main

usedJSHeapSize

  • create10k: unsure 🔍 +0% - +0% (+0.00ms - +0.00ms)
    preact-local vs preact-main
  • filter-list: unsure 🔍 -0% - +0% (-0.00ms - +0.00ms)
    preact-local vs preact-main
  • hydrate1k: unsure 🔍 -2% - +8% (-0.11ms - +0.54ms)
    preact-local vs preact-main
  • many-updates: unsure 🔍 -0% - +0% (-0.00ms - +0.00ms)
    preact-local vs preact-main
  • replace1k: unsure 🔍 -0% - +0% (-0.01ms - +0.01ms)
    preact-local vs preact-main
  • text-update: unsure 🔍 -6% - +2% (-0.06ms - +0.02ms)
    preact-local vs preact-main
  • todo: slower ❌ 1% - 5% (0.01ms - 0.06ms)
    preact-local vs preact-main
  • update10th1k: unsure 🔍 -1% - +0% (-0.02ms - +0.01ms)
    preact-local vs preact-main

Results

create10k

duration

VersionAvg timevs preact-localvs preact-main
preact-local904.35ms - 910.43ms-unsure 🔍
-0% - +1%
-4.46ms - +5.66ms
preact-main902.74ms - 910.84msunsure 🔍
-1% - +0%
-5.66ms - +4.46ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local19.19ms - 19.19ms-unsure 🔍
+0% - +0%
+0.00ms - +0.00ms
preact-main19.19ms - 19.19msunsure 🔍
-0% - -0%
-0.00ms - -0.00ms
-
filter-list

duration

VersionAvg timevs preact-localvs preact-main
preact-local16.49ms - 16.77ms-unsure 🔍
-1% - +2%
-0.16ms - +0.27ms
preact-main16.42ms - 16.73msunsure 🔍
-2% - +1%
-0.27ms - +0.16ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local1.56ms - 1.56ms-unsure 🔍
-0% - +0%
-0.00ms - +0.00ms
preact-main1.56ms - 1.56msunsure 🔍
-0% - +0%
-0.00ms - +0.00ms
-
hydrate1k

duration

VersionAvg timevs preact-localvs preact-main
preact-local60.30ms - 61.66ms-unsure 🔍
-1% - +2%
-0.48ms - +1.32ms
preact-main59.97ms - 61.15msunsure 🔍
-2% - +1%
-1.32ms - +0.48ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local7.03ms - 7.49ms-unsure 🔍
-2% - +8%
-0.11ms - +0.54ms
preact-main6.83ms - 7.27msunsure 🔍
-7% - +1%
-0.54ms - +0.11ms
-
many-updates

duration

VersionAvg timevs preact-localvs preact-main
preact-local16.51ms - 16.56ms-unsure 🔍
-0% - +0%
-0.06ms - +0.07ms
preact-main16.47ms - 16.60msunsure 🔍
-0% - +0%
-0.07ms - +0.06ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local3.72ms - 3.72ms-unsure 🔍
-0% - +0%
-0.00ms - +0.00ms
preact-main3.71ms - 3.72msunsure 🔍
-0% - +0%
-0.00ms - +0.00ms
-
replace1k
  • Browser: chrome-headless
  • Sample size: 100
  • Built by: CI #5378
  • Commit: 1fb2bcc

duration

VersionAvg timevs preact-localvs preact-main
preact-local60.50ms - 61.91ms-unsure 🔍
-2% - +1%
-1.11ms - +0.85ms
preact-main60.66ms - 62.02msunsure 🔍
-1% - +2%
-0.85ms - +1.11ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local3.01ms - 3.03ms-unsure 🔍
-0% - +0%
-0.01ms - +0.01ms
preact-main3.01ms - 3.02msunsure 🔍
-0% - +0%
-0.01ms - +0.01ms
-

run-warmup-0

VersionAvg timevs preact-localvs preact-main
preact-local27.42ms - 28.23ms-unsure 🔍
-1% - +4%
-0.16ms - +0.98ms
preact-main27.01ms - 27.82msunsure 🔍
-4% - +1%
-0.98ms - +0.16ms
-

run-warmup-1

VersionAvg timevs preact-localvs preact-main
preact-local33.47ms - 34.81ms-unsure 🔍
-1% - +4%
-0.50ms - +1.33ms
preact-main33.10ms - 34.35msunsure 🔍
-4% - +1%
-1.33ms - +0.50ms
-

run-warmup-2

VersionAvg timevs preact-localvs preact-main
preact-local34.27ms - 35.77ms-unsure 🔍
-4% - +2%
-1.26ms - +0.74ms
preact-main34.62ms - 35.94msunsure 🔍
-2% - +4%
-0.74ms - +1.26ms
-

run-warmup-3

VersionAvg timevs preact-localvs preact-main
preact-local27.36ms - 28.10ms-unsure 🔍
-1% - +2%
-0.29ms - +0.63ms
preact-main27.29ms - 27.83msunsure 🔍
-2% - +1%
-0.63ms - +0.29ms
-

run-warmup-4

VersionAvg timevs preact-localvs preact-main
preact-local24.93ms - 26.31ms-unsure 🔍
-3% - +5%
-0.76ms - +1.19ms
preact-main24.72ms - 26.09msunsure 🔍
-5% - +3%
-1.19ms - +0.76ms
-

run-final

VersionAvg timevs preact-localvs preact-main
preact-local22.79ms - 23.26ms-unsure 🔍
-1% - +2%
-0.27ms - +0.41ms
preact-main22.71ms - 23.21msunsure 🔍
-2% - +1%
-0.41ms - +0.27ms
-
text-update
  • Browser: chrome-headless
  • Sample size: 240
  • Built by: CI #5378
  • Commit: 1fb2bcc

duration

VersionAvg timevs preact-localvs preact-main
preact-local1.87ms - 1.96ms-unsure 🔍
-5% - +2%
-0.10ms - +0.03ms
preact-main1.90ms - 2.00msunsure 🔍
-2% - +5%
-0.03ms - +0.10ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local1.02ms - 1.07ms-unsure 🔍
-6% - +2%
-0.06ms - +0.02ms
preact-main1.03ms - 1.10msunsure 🔍
-2% - +6%
-0.02ms - +0.06ms
-
todo
  • Browser: chrome-headless
  • Sample size: 110
  • Built by: CI #5378
  • Commit: 1fb2bcc

duration

VersionAvg timevs preact-localvs preact-main
preact-local33.57ms - 33.92ms-unsure 🔍
-0% - +1%
-0.11ms - +0.34ms
preact-main33.50ms - 33.77msunsure 🔍
-1% - +0%
-0.34ms - +0.11ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local1.31ms - 1.34ms-slower ❌
1% - 5%
0.01ms - 0.06ms
preact-main1.27ms - 1.30msfaster ✔
1% - 4%
0.01ms - 0.06ms
-
update10th1k

duration

VersionAvg timevs preact-localvs preact-main
preact-local32.84ms - 34.88ms-unsure 🔍
-4% - +4%
-1.32ms - +1.24ms
preact-main33.13ms - 34.67msunsure 🔍
-4% - +4%
-1.24ms - +1.32ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local2.97ms - 2.98ms-unsure 🔍
-1% - +0%
-0.02ms - +0.01ms
preact-main2.97ms - 2.99msunsure 🔍
-0% - +1%
-0.01ms - +0.02ms
-

tachometer-reporter-action v2 for CI

@github-actions
Copy link

github-actions bot commented Feb 10, 2026

Size Change: +70 B (+0.09%)

Total Size: 78.8 kB

Filename Size Change
dist/preact.js 4.72 kB +9 B (+0.19%)
dist/preact.min.js 4.74 kB +11 B (+0.23%)
dist/preact.min.module.js 4.75 kB +8 B (+0.17%)
dist/preact.min.umd.js 4.76 kB +10 B (+0.21%)
dist/preact.mjs 4.74 kB +10 B (+0.21%)
dist/preact.module.js 4.74 kB +10 B (+0.21%)
dist/preact.umd.js 4.77 kB +12 B (+0.25%)
ℹ️ View Unchanged
Filename Size
compat/dist/compat.js 4.18 kB
compat/dist/compat.mjs 4.11 kB
compat/dist/compat.module.js 4.11 kB
compat/dist/compat.umd.js 4.25 kB
debug/dist/debug.js 3.85 kB
debug/dist/debug.mjs 3.85 kB
debug/dist/debug.module.js 3.85 kB
debug/dist/debug.umd.js 3.93 kB
devtools/dist/devtools.js 260 B
devtools/dist/devtools.mjs 274 B
devtools/dist/devtools.module.js 274 B
devtools/dist/devtools.umd.js 346 B
hooks/dist/hooks.js 1.53 kB
hooks/dist/hooks.mjs 1.56 kB
hooks/dist/hooks.module.js 1.56 kB
hooks/dist/hooks.umd.js 1.6 kB
jsx-runtime/dist/jsxRuntime.js 1.01 kB
jsx-runtime/dist/jsxRuntime.mjs 985 B
jsx-runtime/dist/jsxRuntime.module.js 985 B
jsx-runtime/dist/jsxRuntime.umd.js 1.08 kB
test-utils/dist/testUtils.js 473 B
test-utils/dist/testUtils.mjs 477 B
test-utils/dist/testUtils.module.js 477 B
test-utils/dist/testUtils.umd.js 555 B

compressed-size-action

@JoviDeCroock JoviDeCroock force-pushed the remove-act-leak-in-core branch from 3d98a77 to db2c2fc Compare February 10, 2026 10:33
@JoviDeCroock JoviDeCroock changed the title Remove leaking act implementation into core Ensure we reset renderCount Feb 10, 2026
@JoviDeCroock JoviDeCroock force-pushed the remove-act-leak-in-core branch from 069a131 to b81c0c4 Compare February 16, 2026 17:59
renderComponent(c);
}
} finally {
rerenderQueue.length = process._rerenderCount = 0;
Copy link
Member Author

Choose a reason for hiding this comment

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

This is up for debate, we could also just wrap renderComponent in this try {} catch {} and throw the first error so that we do process the rest of the queue

@JoviDeCroock JoviDeCroock merged commit 55254ef into v10.x Feb 26, 2026
12 checks passed
@JoviDeCroock JoviDeCroock deleted the remove-act-leak-in-core branch February 26, 2026 07:28
@JoviDeCroock JoviDeCroock mentioned this pull request Mar 10, 2026
JoviDeCroock added a commit that referenced this pull request Mar 10, 2026
* Golf some bytes and ensure we reset renderCount

* Apply suggestion from @JoviDeCroock

* Add test

(cherry picked from commit 55254ef)
JoviDeCroock added a commit that referenced this pull request Mar 15, 2026
* Fix crash where a synchronous effect render unmounts the tree (#5026)

(cherry picked from commit 8cbed5f)

* Golf down compat (#5025)

* Make useFlushSync do sync flushes

* Golf bytes to offset change

* Some more golfing

* Revert "Make useFlushSync do sync flushes"

This reverts commit 001bbce.

(cherry picked from commit af4c459)

* Implement flushSync (#5036)

(cherry picked from commit 978c0b9)

* undefined prototype (#5041)

* undefined prototype

* Add test

(cherry picked from commit b341bfe)

* Ensure we reset renderCount (#5017)

* Golf some bytes and ensure we reset renderCount

* Apply suggestion from @JoviDeCroock

* Add test

(cherry picked from commit 55254ef)

* fix(compat): export StrictMode directly
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.

2 participants