Describe the bug
When load the page in the first time or click the "refresh" button in browser, the client side js is going to remove all html nodes rendered in server side, and then render them again.
To Reproduce
npx degit "sveltejs/sapper-template#rollup" my-app)
Expected behavior
Sapper shouldn't remove those html nodes in first time rendering.
Information about your Sapper Installation:
Your hosting environment: Local
Sapper version: 0.27.9
Svelte version: 3.12.1
If it is an exported (npm run export) or dynamic application: dynamic
Whether your application uses Webpack or Rollup: Rollup
Is this a bug with Sapper or a problem with Svelte's hydration?
Why is this a problem at all? It's documented behavior.
That should not an expected behaviour because removing all DOM nodes inside your APP node on the client after SSR should not happen. What else would be the advantage of SSR? It is as if you were using CSR. Hydration is okay.
The main reason for doing SSR is that the time for the first meaningful paint is lower and that it's easier for search engines to crawl and index your website. Recreating the DOM client-side doesn't impact this at all.
If this is happening, then it is definitely a bug. Removing everything and recreating it is wasteful and not how SSR is supposed to work. There are benefits to delivering static-content even without hydration but it is this hydration process that makes it a powerful pattern, despite the problems it poses.
How is it a bug? It's right there in the documentation:
Whereas children of target are normally left alone,
hydrate: truewill cause any children to be removed.
Because Svelte 'claims' nodes as long as the structures of the static version and dynamic version match, if these two versions of the site do not match then it will indeed bail and destroy them. Here is the relevant runtime code.
This distinction is mentioned in the docs because without hydration Svelte appends (ignoring other DOM), with hydration Svelte forces the contents to match whatever is inside you Svelte app. This is discussed in the docs to prevent duplicate DOM when building a static version and to prevent accidental removal when hydrating.
When re-hydrating a component, Svelte "claims" all of the child nodes that are still needed/wanted; removes all of the leftover unwanted nodes; and then re-appends the needed nodes to ensure they're in the correct order.
The flickering is because when breaking on DOM modifications, foo.appendChild(bar); is treated as first removing bar from the DOM and then re-inserting it into the DOM at the end of foo's child list. The debugger is exposing this intermediate step within appendChild, even though from the JS code's perspective it's an atomic operation.
The other aspect is that if you have a component X with children [A, B, C], because the component is mounted by re-appending the children, you'll visually see the nodes cycle around:
X.appendChild(A) => [B, C, A] (A moved to the end)
X.appendChild(B) => [C, A, B] (B moved to the end)
X.appendChild(C) => [A, B, C] (C moved to the end)
This is a consequence of using the same generic mount implementation for both the rehydration process (i.e., after claiming) and for the normal component construction lifecycle (i.e., after createing).
I don't know enough about the browser paint cycle to know if this could ever actually be visible to a normal user (i.e., outside of debugging). But "fixing" it would probably require changing the Svelte compiler to emit a call like setChildren(X, [A, B, C]), which can then more intelligently check that X's children are exactly those three nodes in that order, and elide DOM operations when they're not necessary.
I don't know enough about the browser paint cycle to know if this could ever actually be visible to a normal user (i.e., outside of debugging).
In my case the javascript engages about a second after site load, if a user enters something into the auto focused input field in that second, it is cleared by this and looses focus.
Svelte should actually just take possession of the existing elements.
@pngwn can I ask you why the pending clarification tag on this issue?
I think this is really a bug and maybe the correct tag could increase its resolution priority. Am I wrong?
Has anyone found a way to get around in the meantime?
Here is a gif for you.
See the Date.now() value and the green re-painting:

This is particularly a problem when you have animations (even just css) on the elements as soon as they are rendered.
There are a number of issues tracking this over in the Svelte repo with a list of some of them in https://github.com/sveltejs/svelte/issues/4975. I agree this could be improved, but it has to be addressed in Svelte, so I'm going to close this one in favor of the Svelte issues
Most helpful comment
This is particularly a problem when you have animations (even just css) on the elements as soon as they are rendered.