Batch updates in flushSync - #5173
Merged
Merged
Conversation
|
Size Change: +59 B (+0.07%) Total Size: 79.5 kB 📦 View Changed
ℹ️ View Unchanged
|
📊 Tachometer Benchmark ResultsSummaryduration
usedJSHeapSize
Resultscreate10kduration
usedJSHeapSize
filter-listduration
usedJSHeapSize
hydrate1kduration
usedJSHeapSize
many-updatesduration
usedJSHeapSize
replace1kduration
usedJSHeapSize
run-warmup-0
run-warmup-1
run-warmup-2
run-warmup-3
run-warmup-4
run-final
text-updateduration
usedJSHeapSize
tododuration
usedJSHeapSize
update10th1kduration
usedJSHeapSize
|
marvinhagemeister
approved these changes
Jul 29, 2026
JoviDeCroock
added a commit
to ssssota/preactjs_preact
that referenced
this pull request
Jul 31, 2026
Previously, flushSync temporarily configured options.debounceRendering to execute every scheduled render immediately. This made updates synchronous, but it also caused each state setter to render independently instead of batching all updates performed inside the callback into one synchronous commit. Capture the scheduled render callback while the user callback runs, then flush it once before returning. The previous debounce function is restored in a finally block. Mirrors preactjs#5173 (v10.x).
Merged
valthon
added a commit
to valthon/zigapagos
that referenced
this pull request
Aug 8, 2026
… injection fix Supersedes dependabot PR #124 (happy-dom 20.11.0 -> 20.11.1); the sweep below was researched against each package's releases rather than taking the grouped bump as-is. preact-render-to-string ^6.6.2 -> ^6.7.0 is the change that matters on its own. 6.7.0 reordered the attribute serializer so UNSAFE_NAME rejection runs before namespace normalization (preactjs/preact-render-to-string#461): previously an attribute key that looked namespaced but contained spaces or `>` was rewritten and emitted rather than dropped — markup injection through prop KEYS, e.g. `xlinkHref><script>…`. That lands on our only SSR path: runtime/src/core.ts re-exports renderToString and runtime/sidecar/render.ts drives it with author-content props from src/islands/props.zig. The lockfile already resolved 6.7.0, so built sites were safe; the declared ^6.6.2 was the hole, because any fresh resolution could legally land back on the vulnerable 6.6.2. Raising the floor closes it. preact ^10.29.7 -> ^10.29.8: two perf fixes — flushSync now actually batches (preactjs/preact#5173; we re-export it but never call it) and retained-subtree traversal is skipped after sCU/memo bailouts (#5182). Diff-layer change, so validated through bun test (750/0) plus a full examples/tsx-site build (SSR + hydration bundle + CSP emitters). happy-dom + @happy-dom/global-registrator ^20.11.0 -> ^20.11.2 (lockstep, as they release): 20.11.1 stops constructing DOMException on the query-selector hot path (a straight speedup for this DOM-heavy suite); 20.11.2 fixes MutationObserver callbacks being held only via WeakRef and silently dying after a GC — latent here, but exactly the class of defect that presents as an unreproducible flaky test. typescript stays at ^6.0.3 — and permanently, not pending a 6.1: 6.0.3 is the final release of the JavaScript codebase (microsoft/TypeScript#62963, the 6.0 line is in maintenance mode; the next stable on the registry is the Go-based 7.0.2, which ships no JS compiler API). The dependabot.yml cap below 7.0.0 and its unblock conditions (7.1's new API, expected ~Oct 2026, then porting the three ts.createSourceFile call sites) are unchanged. All three lockfiles are regenerated in this commit (rm bun.lock + install, per the dependabot.yml note — site/ and examples/tsx-site embed their own copy of @z/runtime's resolved set and a plain install does not refresh it), under the newly pinned bun 1.3.14 so the lockfiles are canonical for the toolchain that CI runs. The two regenerated trees are pinned back to "configVersion": 0: a from-scratch lockfile is treated as a new project and stamped configVersion 1, which flips future installs to the isolated linker — a silent node_modules-layout change this repo doesn't want, since props_check.zig resolves tsc from the website root's hoisted tree. 0 is the value runtime/'s lockfile already carries and preserves hoisted semantics; frozen installs from scratch were verified to honor it (no .bun store, tsc resolvable at top level). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
HeyItsGilbert
added a commit
to HeyItsGilbert/DigitalGarden
that referenced
this pull request
Aug 23, 2026
 <h3>Snyk has created this PR to upgrade preact from 10.29.7 to 10.29.8.</h3> :information_source: Keep your dependencies up-to-date. This makes it easier to fix existing vulnerabilities and to more quickly identify and fix newly disclosed vulnerabilities when they affect your project. <hr/> - The recommended version is **1 version** ahead of your current version. - The recommended version was released **21 days ago**. #### Breaking Change Risk  > **Notice:** This assessment is enhanced by AI. <details> <summary><b>Release notes</b></summary> <br/> <details> <summary>Package name: <b>preact</b></summary> <ul> <li> <b>10.29.8</b> - <a href="https://redirect.github.com/preactjs/preact/releases/tag/10.29.8">2026-08-01</a></br><h2>Performance</h2> <ul> <li>Batch updates in flushSync (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="4946206960" data-permission-text="Title is private" data-url="preactjs/preact#5173" data-hovercard-type="pull_request" data-hovercard-url="/preactjs/preact/pull/5173/hovercard" href="https://redirect.github.com/preactjs/preact/pull/5173">#5173</a>, thanks <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/JoviDeCroock/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://redirect.github.com/JoviDeCroock">@ JoviDeCroock</a>)</li> <li>Avoid traversing retained subtrees (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="5010720925" data-permission-text="Title is private" data-url="preactjs/preact#5182" data-hovercard-type="pull_request" data-hovercard-url="/preactjs/preact/pull/5182/hovercard" href="https://redirect.github.com/preactjs/preact/pull/5182">#5182</a>, thanks <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/JoviDeCroock/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://redirect.github.com/JoviDeCroock">@ JoviDeCroock</a>)</li> </ul> </li> <li> <b>10.29.7</b> - <a href="https://redirect.github.com/preactjs/preact/releases/tag/10.29.7">2026-07-08</a></br><h2>Maintenance</h2> <ul> <li>Make RTS optional peer dep (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="4839540392" data-permission-text="Title is private" data-url="preactjs/preact#5150" data-hovercard-type="pull_request" data-hovercard-url="/preactjs/preact/pull/5150/hovercard" href="https://redirect.github.com/preactjs/preact/pull/5150">#5150</a>, thanks <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/JoviDeCroock/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://redirect.github.com/JoviDeCroock">@ JoviDeCroock</a>)</li> </ul> </li> </ul> from <a href="https://redirect.github.com/preactjs/preact/releases">preact GitHub release notes</a> </details> </details> --- > [!IMPORTANT] > > - Check the changes in this PR to ensure they won't cause issues with your project. > - This PR was automatically created by Snyk using the credentials of a real user. --- **Note:** _You are seeing this because you or someone else with access to this repository has authorized Snyk to open upgrade PRs._ **For more information:** <img src="https://api.segment.io/v1/pixel/track?data=eyJ3cml0ZUtleSI6InJyWmxZcEdHY2RyTHZsb0lYd0dUcVg4WkFRTnNCOUEwIiwiYW5vbnltb3VzSWQiOiI1NGI1MmJmOS05Yjk4LTQxOTktOTljNS0zZmM0NTZhNmEzYjIiLCJldmVudCI6IlBSIHZpZXdlZCIsInByb3BlcnRpZXMiOnsicHJJZCI6IjU0YjUyYmY5LTliOTgtNDE5OS05OWM1LTNmYzQ1NmE2YTNiMiJ9fQ==" width="0" height="0"/> > - 🧐 [View latest project report](https://app.snyk.io/org/heyitsgilbert/project/b4d35463-698d-4f18-a0ef-2b34051c2638?utm_source=github&utm_medium=referral&page=upgrade-pr) > - 📜 [Customise PR templates](https://docs.snyk.io/scan-using-snyk/pull-requests/snyk-fix-pull-or-merge-requests/customize-pr-templates?utm_source=&utm_content=fix-pr-template) > - 🛠 [Adjust upgrade PR settings](https://app.snyk.io/org/heyitsgilbert/project/b4d35463-698d-4f18-a0ef-2b34051c2638/settings/integration?utm_source=github&utm_medium=referral&page=upgrade-pr) > - 🔕 [Ignore this dependency or unsubscribe from future upgrade PRs](https://app.snyk.io/org/heyitsgilbert/project/b4d35463-698d-4f18-a0ef-2b34051c2638/settings/integration?pkg=preact&utm_source=github&utm_medium=referral&page=upgrade-pr#auto-dep-upgrades) [//]: # 'snyk:metadata:{"breakingChangeRiskLevel":"low","FF_showPullRequestBreakingChanges":true,"FF_showPullRequestBreakingChangesWebSearch":false,"customTemplate":{"variablesUsed":[],"fieldsUsed":[]},"dependencies":[{"name":"preact","from":"10.29.7","to":"10.29.8"}],"env":"prod","hasFixes":false,"isBreakingChange":false,"isMajorUpgrade":false,"issuesToFix":[],"prId":"54b52bf9-9b98-4199-99c5-3fc456a6a3b2","prPublicId":"54b52bf9-9b98-4199-99c5-3fc456a6a3b2","packageManager":"npm","priorityScoreList":[],"projectPublicId":"b4d35463-698d-4f18-a0ef-2b34051c2638","projectUrl":"https://app.snyk.io/org/heyitsgilbert/project/b4d35463-698d-4f18-a0ef-2b34051c2638?utm_source=github&utm_medium=referral&page=upgrade-pr","prType":"upgrade","templateFieldSources":{"branchName":"default","commitMessage":"default","description":"default","title":"default"},"templateVariants":[],"type":"auto","upgrade":[],"upgradeInfo":{"versionsDiff":1,"publishedDate":"2026-08-01T09:59:54.572Z"},"vulns":[]}' Co-authored-by: snyk-bot <snyk-bot@snyk.io>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Make
preact/compat’sflushSyncbatch updates performed inside its callback.Previously,
flushSynctemporarily configuredoptions.debounceRenderingto execute every scheduled render immediately. This made updates synchronous, but it also caused each state setter to render independently:The example above could render twice instead of batching both updates into one synchronous commit.
This change captures the scheduled render callback while the user callback runs, then flushes it once before returning. The previous debounce function is restored in a
finallyblock.Results
Measured with Octane’s nested update benchmark:
Non-batched update timings remain unchanged.