Skip to content

Conversation

@JoviDeCroock
Copy link
Member

@JoviDeCroock JoviDeCroock commented Jul 27, 2025

Consider the following scenario, we have an application with a shell:

App
  Header
  Suspense
    ErrorBoundary
      Body --> Async
  Footer

We server-side render the HTML, send it to the client. The client starts hydrating and we do that successfully up to the Body, the Body will throw a Promise and we'll suspend. This means that the Header/Footer will be interactive the the Body won't be, when Body loads we continue hydration but there is an error in the component.

When there is an error we remove the existing DOM as hydration is considered useless and we need to render the ErrorBoundary. When the ErrorBoundary is set to retry immediately we'll attempt to re-render the component. With Signals (and PureComponent/...) there's a chance that we now bail out of rendering, we'd bail out of rendering while having a partially mutated oldVNode. The oldVNode would signal that it has _component and hence is not new while being absent from _children as we never reached diffChildren.

This PR will ensure that when we error that we must consider the update as forced, this ensures that we never bail out of rendering and that any erroneous state that could be in the component is reset.

Initially I had a simpler solution where I would set vnode._component to null but that means that we'd break components catching their own error. Hence why I got to a solution that requires a bit more bytes but solves most of the issues. In reality the else branch isn't really needed for the issue at hand but I'd prefer being safe.

Big thanks to @joel-solymosi for finding this issue and providing the hints we needed.

The issue was introduced in #4563

Supersedes #4854
Supersedes #4822

@JoviDeCroock JoviDeCroock marked this pull request as ready for review July 27, 2025 19:22
@github-actions
Copy link

github-actions bot commented Jul 27, 2025

📊 Tachometer Benchmark Results

Summary

A summary of the benchmark results will show here once they finish.

Results

The full results of your benchmarks will show here once they finish.

tachometer-reporter-action v2 for CI

@github-actions
Copy link

github-actions bot commented Jul 27, 2025

Size Change: +221 B (+0.28%)

Total Size: 78.9 kB

Filename Size Change
dist/preact.js 4.77 kB +31 B (+0.65%)
dist/preact.min.js 4.79 kB +32 B (+0.67%)
dist/preact.min.module.js 4.79 kB +31 B (+0.65%)
dist/preact.min.umd.js 4.81 kB +31 B (+0.65%)
dist/preact.mjs 4.78 kB +32 B (+0.67%)
dist/preact.module.js 4.78 kB +32 B (+0.67%)
dist/preact.umd.js 4.82 kB +32 B (+0.67%)
ℹ️ View Unchanged
Filename Size
compat/dist/compat.js 4.15 kB
compat/dist/compat.mjs 4.08 kB
compat/dist/compat.module.js 4.08 kB
compat/dist/compat.umd.js 4.21 kB
debug/dist/debug.js 3.82 kB
debug/dist/debug.mjs 3.82 kB
debug/dist/debug.module.js 3.82 kB
debug/dist/debug.umd.js 3.9 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.54 kB
hooks/dist/hooks.mjs 1.57 kB
hooks/dist/hooks.module.js 1.57 kB
hooks/dist/hooks.umd.js 1.61 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

Copy link
Member

@rschristian rschristian left a comment

Choose a reason for hiding this comment

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

Great find!

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.

LGTM

@JoviDeCroock JoviDeCroock merged commit 6fea157 into v10.x Jul 28, 2025
11 of 12 checks passed
@JoviDeCroock JoviDeCroock deleted the ensure-we-rerender branch July 28, 2025 08:14
@JoviDeCroock JoviDeCroock mentioned this pull request Jul 28, 2025
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.

4 participants