Skip to content

Unexpected DOM mutations during hydration #8267

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

Closed
ebeloded opened this issue Jan 17, 2023 · 4 comments
Closed

Unexpected DOM mutations during hydration #8267

ebeloded opened this issue Jan 17, 2023 · 4 comments
Milestone

Comments

@ebeloded
Copy link

ebeloded commented Jan 17, 2023

Describe the bug

When hydrating a server-side-rendered page, Svelte applies numerous unexpected mutations—mainly removing and adding empty text nodes. The number of mutations seems to grow linearly with the number of components.

Here, for example, mutation logs from a bare-bone https://node.new/sveltekit project:

CleanShot 2023-01-17 at 15 35 17@2x

The expected behavior is to observe no mutations, unless something has changed. Please note that the issue I am describing is observed in production build, not only in development (where some mutations are justified).

Reproduction

To reproduce, one can just add a MutationObserver to app.html:

<body data-sveltekit-preload-data="hover">
  <div style="display: contents" id="kit-body">%sveltekit.body%</div>
</body>
<script>
  // Callback function to execute when mutations are observed
  const callback = (mutationList, observer) => {
    for (const mutation of mutationList) {
      console.log(mutation);
    }
  };

  // Create an observer instance linked to the callback function
  const observer = new MutationObserver(callback);

  // Start observing the target node for configured mutations
  observer.observe(document.getElementById('kit-body'), {
    attributes: true,
    childList: true,
    subtree: true,
    attributeOldValue: true
  });
</script>

Reproduction in github repo (contains SvelteKit skeleton, with mutation observer in app.html)

Logs

No response

System Info

System:
    OS: macOS 13.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 92.84 MB / 32.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 16.19.0 - ~/.nvm/versions/node/v16.19.0/bin/node
    npm: 8.19.3 - ~/.nvm/versions/node/v16.19.0/bin/npm
  Browsers:
    Chrome: 108.0.5359.124
    Firefox: 108.0.1
    Safari: 16.2
  npmPackages:
    @sveltejs/adapter-auto: ^1.0.0 => 1.0.1 
    @sveltejs/kit: ^1.0.0 => 1.1.1 
    svelte: ^3.54.0 => 3.55.1 
    vite: ^4.0.0 => 4.0.4

Severity

Performing DOM manipulations on load can have unpleasant side effects. I discovered the issue while trying to figure out, why CSS animation on a server-rendered element was being reset during hydration.

@Rich-Harris
Copy link
Member

This is a Svelte issue rather than a SvelteKit issue — transferring to that repo

@Rich-Harris Rich-Harris transferred this issue from sveltejs/kit Feb 9, 2023
@benmccann
Copy link
Member

@ebeloded would you be able to check if this issue is still present in Svelte 4?

@ebeloded
Copy link
Author

@benmccann yes, I can confirm that the problem persists with Svelte 4.

I created a reproduction in stackblitz with svelte 4, which contains the default app + mutations observer added in app.html:

https://stackblitz.com/edit/sveltejs-kit-template-default-c4ryyv

In the console you can see the log of applied mutations - most of them are about adding/removing empty text nodes:
CleanShot 2023-06-26 at 08 42 48@2x

The desired behavior is to have none of those mutations.

@Rich-Harris Rich-Harris added this to the 5.0 milestone Apr 2, 2024
@dummdidumm
Copy link
Member

The are no more hydration mutations in the example in Svelte 5. The two that are left are from the announcer that is inserted on mount. Therefore closing.

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

No branches or pull requests

4 participants