Skip to content

Hydration & zoneless: elements got rerendered after Angular initializes #62672

Closed

Description

@zip-fa

Which @angular/* package(s) are the source of the bug?

core

Is this a regression?

No

Description

Hey,
I've noticed that on each page load, after Angular initializes, all element attributes get re-rendered. This is easy to see with the "Rendering -> Paint flashing" option enabled in dev tools & console.logs from mutation observer.

I've added an app initializer that blocks rendering for 1 second and registers a mutation observer to track all attribute changes:

provideAppInitializer(() => {
      return new Promise((resolve) => {
        if (typeof window !== 'undefined') {
            // mutation observer for console.logs
        }

        setTimeout(() => {
          resolve(true);
        }, 1000);
      });
    })
2025-07-16.22.50.47.mov

According to the docs:

Hydration is the process that restores the server-side rendered application on the client. This includes things like reusing the server rendered DOM structures, persisting the application state, transferring application data that was retrieved already by the server, and other processes.

Do I understand correctly that in this case, hydration simply doesn't work?

Please provide a link to a minimal reproduction of the bug

https://github.com/zip-fa/ng20-hydration-issue

Please provide the exception or error you saw


Please provide the environment you discovered this bug in (run ng version)

Angular: 20.1.1
... common, compiler, compiler-cli, core, forms, localize
... platform-browser, platform-server, router

Package                      Version
------------------------------------------------------
@angular-devkit/architect    0.2001.0
@angular-devkit/core         20.1.1
@angular-devkit/schematics   20.1.1
@angular/build               20.1.1
@angular/cli                 20.1.1
@angular/ssr                 20.1.1
@schematics/angular          20.1.1
rxjs                         7.8.2
typescript                   5.8.3

Anything else?

ng build && node dist/ng20-hydration-issue/server/server.mjs

Activity

  1. atscott commented on Jul 16, 2025

    @atscott
    Contributor

    I believe this might be fixed by #62631. Can you update to 20.1.1 to see if the issue is resolved?

  2. zip-fa commented on Jul 16, 2025

    @zip-fa
    Author

    Sorry, i gave invalid environment output, i am already on 20.1.1

    I believe this might be fixed by #62631. Can you update to 20.1.1 to see if the issue is resolved?

  3. atscott commented on Jul 16, 2025

    @atscott
    Contributor

    Ah, this is unrelated to zoneless.

  4. JeanMeche commented on Jul 16, 2025

    @JeanMeche
    Member

    This is probably a variant of #61231, the router outlet also relies on createComponent.

  5. zip-fa commented on Jul 17, 2025

    @zip-fa
    Author

    This is probably a variant of #61231, the router outlet also relies on createComponent.

    Take a look at console output: root ng-version (which is unrelated to app logic, router etc) gets re-rendered too (version changes from 20.1.1 to 20.1.1).

    That means hydration doesn't work at all even with minimal setup in new project.

  6. zip-fa commented on Jul 17, 2025

    @zip-fa
    Author

    I've updated my repro: now i don't use router. Flicker & rerender still occurs as it was.
    I verified that in dev mode angular reports that hydration was successful:

    Angular hydrated 1 component(s) and 10 node(s), 0 component(s) were skipped. Learn more at https://angular.dev/guide/hydration.

    Code minimized to:

    import {ChangeDetectionStrategy, Component, signal} from '@angular/core';
    
    @Component({
      selector: 'app-root',
      template: `
        Hey<br/><br/><br/><br/><br/><br/>
    
        <div style="display: flex; gap: 10px">
          <!--<img ngSrc="non-existent-image.png" width="500" height="500" style="border: 1px solid black" />-->
          <!--<img src="non-existent-image.png" width="500" height="500" style="border: 1px solid black" />-->
    
          <img
            [attr.data-test]="test()"
            (click)="test.set(true)"
            src="https://images.dog.ceo/breeds/papillon/n02086910_2994.jpg" width="500" height="500" style="border: 1px solid black" />
        </div>
      `,
      changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class App {
      test = signal(false);
    }
  7. added this to the needsTriage milestone on Jul 17, 2025
  8. AndrewKushnir commented on Jul 19, 2025

    @AndrewKushnir
    Contributor

    I've noticed that on each page load, after Angular initializes, all element attributes get re-rendered. This is easy to see with the "Rendering -> Paint flashing" option enabled in dev tools & console.logs from mutation observer.

    The issue with the image is probably caused by the fact that you have devtools open and likely network cache is disabled, thus you are seeing a flicker on the image element (which is being re-fetched, even though the URL remains the same). @arturovt did an exploration earlier (see #52478 (comment)) and the problem with reloading in prod environment was only affecting <object>, <embed> and <iframe> elements.

    Please let us know if you've noticed this issue in production environment as well or it only affects dev environment.

  9. zip-fa commented on Jul 19, 2025

    @zip-fa
    Author

    I've noticed that on each page load, after Angular initializes, all element attributes get re-rendered. This is easy to see with the "Rendering -> Paint flashing" option enabled in dev tools & console.logs from mutation observer.

    The issue with the image is probably caused by the fact that you have devtools open and likely network cache is disabled, thus you are seeing a flicker on the image element (which is being re-fetched, even though the URL remains the same). @arturovt did an exploration earlier (see #52478 (comment)) and the problem with reloading in prod environment was only affecting <object>, <embed> and <iframe> elements.

    Please let us know if you've noticed this issue in production environment as well or it only affects dev environment.

    Yes. We noticed this in prod w/o dev tools opened and started to dig. We noticed that elements with @Animations are playing twice because attribute changes the same way i recorded in dev tools. I will update my repro again covering this too and will add block with stream of mutation observer updates to better understand what's going on

  10. thePunderWoman commented on Jul 22, 2025

    @thePunderWoman
    Contributor

    I ran both dev and prod locally, and hydration appears to be working. In dev I was able to confirm without changing anything that all the elements present have hydrated properly. I saw no issues with hydration in production mode either. There's the initial browser fetching of the image URL, but that's all I see otherwise.

  11. JeanMeche commented on Jun 8, 2026

    @JeanMeche
    Member

    Is this still an issue ? (From Jess' comment, I would guess no).

  12. zip-fa commented on Jun 8, 2026

    @zip-fa
    Author

    No, this was related to my another issue.

  13. angular-automatic-lock-bot commented on Jul 9, 2026

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  14. locked and limited conversation to collaborators on Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions