-
Notifications
You must be signed in to change notification settings - Fork 26.3k
Bug: ssr + zoneless + defer + inputs fails to resolve input data on first render #61038
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
Comments
I was able to see the same thing with the repro. I'll look further into it to see what's going on here. |
This actually is not just a pre-rendering issue. It also impacts SSR overall. Zoneless is currently experimental and we're still working on stabilizing it specifically with SSR cases. There's a callout in the Zoneless guide mentioning feature gaps with SSR around timing of serialization and it happening too early. This is the exact thing happening. The interesting thing is that the incremental hydration behavior is working just fine and as intended. The issue is actually the signal input. Serialization seems to happen before that signal input task is resolved. The fix takes care of it with rendering after a macrotask. angular/angular-cli@6bd7b9b Given that this is experimental still, I don't think we'd backport it, but it probably warrants more investigation as we need to ensure we have the right fix in place for this. |
So it's actually unrelated to signal inputs too. Any type of input post 19.0.4 has this problem, but only on the very very first time the page is rendered. If you hard refresh the page after that, it renders fine. So there's something up with that first render post app-build, which doesn't appear to be on the framework side. We haven't been able to replicate this in a test environment at all either. I think this may be a CLI issue. I'll move this ticket over to that repo for further diagnosis. |
Thank you for the investigation @thePunderWoman Thanks to the details you shared, I've managed to workaround the issue with the following code in the root component: const endTask = this.pendingTasks.add();
setTimeout(() => endTask(), 0); |
I had a deeper look at this and I switched the code to directly call the "low-level" rendering APIs: renderApplication(bootstrap, {
url: '',
document: '<app-root></app-root>',
})
.then(console.log)
.catch(console.error); Even with version <html><head></head><body><!--nghm--><app-root ng-version="19.0.4" ngh="0" ng-server-context="other"><!----><app-hydrated><p></p></app-hydrated><!--ngh=d0--></app-root><script id="ng-state" type="application/json">{"__nghData__":[{"t":{"0":"t0","1":"t1"},"c":{"0":[],"1":[{"i":"t0","r":1,"di":"d0","s":2}]}}],"__nghDeferData__":{"d0":{"p":null,"r":1,"s":2,"t":[]}}}</script></body></html> I added some basic
Looking into the angular/packages/core/src/zone/ng_zone.ts Line 566 in 6c8faaa
While checking how pending task removal is handled for angular/packages/core/src/defer/triggering.ts Line 250 in 2445946
.finally() block seems to resolve this race condition:
return tDetails.loadingPromise.finally(() => {
// Loading is completed, we no longer need the loading Promise
// and the pending task should also be removed.
tDetails.loadingPromise = null;
pendingTasks.remove(taskId);
}); |
Wow, I'm surprised you were able to replicate this in 19.0.4 when I was unable to. For me things worked in 19.0.4 and moving to 19.0.5 showed the reported behavior. So I'm curious what you did differently to see this. We've been unable to replicate in tests. So I'd be interested to see what you've done there. |
This comment has been minimized.
This comment has been minimized.
Previously, the app was marked as stable prematurely. For more details, see angular#61038 (comment) Closes: angular#61038
Previously, the app was marked as stable prematurely. For more details, see angular#61038 (comment) Closes: angular#61038 (cherry picked from commit de649c9)
Previously, the app was marked as stable prematurely. For more details, see #61038 (comment) Closes: #61038 (cherry picked from commit de649c9) PR Close #61056
Previously, the app was marked as stable prematurely. For more details, see #61038 (comment) Closes: #61038 PR Close #61040
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Uh oh!
There was an error while loading. Please reload this page.
Which @angular/* package(s) are the source of the bug?
I don't know
Is this a regression?
Yes
Description
When using incremental hydration with zoneless change detection, the prerendered html (or returned from SSR) is incorrect.
Template is incomplete in the generated HTML for components inside
@defer(hydrate never)
.This behavior seems to be the same no matter the hydrate trigger.
When using zone change detection, the prerendering works fine.
Please provide a link to a minimal reproduction of the bug
https://github.com/jsaguet/ng-zoneless-hydration-prerender
Please provide the exception or error you saw
The generated html in index.html is incorrect:
when it should have been
Please provide the environment you discovered this bug in (run
ng version
)Anything else?
The regression starts with Angular 19.0.5 and seems to have been fixed in 20.0.0-next.4
I'm not sure which commit in the 20.0.0-next.4 release fixes it but it would be great to have it backported to the release 19 even though zoneless is still experimental in this version.
The text was updated successfully, but these errors were encountered: