kit
kit copied to clipboard
First `goto()` call after hot reload and page refresh causes destroy-and-mount and state loss
Describe the bug
First goto()
call after hot reload and page refresh causes a destroy-and-mount and state loss. This state loss and destroy-and-mount can be annoying when developing and the page has heavy initialisation, like network calls and a slippy map in my case.
Logs
β
To Reproduce
- Clone https://github.com/rjkip/sveltekit-destroy-and-mount.
- Run
npm run dev
. - Open
http://localhost:3000
; it redirects to/0
.π§ Count Mount!
is logged to the console. - Click the button a few times; nothing is logged to the console.
- Cause the page to hot-reload by eg. uncommenting the second
++count;
. - Refresh the page.
- Click the button.
- The page's state is lost and
π§ Count Destroy!
andπ§ Count Mount!
are logged to the console.
You may to retry a handful of times and play with hot-reloading/refreshing. I reproduced this several times when writing up this bug, but when I tried again before clicking submit the issue wasn't there...
Expected behavior
- The button always increments the count on first click without losing state and resetting to 0, and the component stays mounted.
Stacktraces
β
Information about your SvelteKit Installation:
Diagnostics
-
The output of
npx envinfo --system --npmPackages svelte,@sveltejs/kit,vite --binaries --browsers
System: OS: Linux 4.19 Ubuntu 20.04.2 LTS (Focal Fossa) CPU: (8) x64 Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz Memory: 364.20 MB / 12.39 GB Container: Yes Shell: 5.8 - /usr/bin/zsh Binaries: Node: 12.22.1 - /usr/bin/node npm: 7.10.0 - ~/.npm-prefix/bin/npm Browsers: Firefox: 88.0.1 npmPackages: @sveltejs/kit: next => 1.0.0-next.109 svelte: ^3.34.0 => 3.38.2
-
Your browser
Firefox 88.0 (64-bit)
-
Your adapter (e.g. Node, static, Vercel, Begin, etc...)
Node
Severity Just annoying, really.
Additional context
β
I have the seme problem, I made a simple example with 3 pages and two buttons.
Initially I navigate to the url http://localhost:3000/site/recibos
, the page is loaded I can see my __layout is loaded in the network tab:
Then I click the button that executes the following command:
<button on:click="{() => goto('/site/empresas')}">Empresas</button>
then I see in the network tab that the __layout is loaded again:
After that subsequent links are working as expected:
<button on:click="{() => goto('/site/legajos')}">Legajos</button>
So, after the first click when the __layout is loaded again everything is destroyed and created again, losing the state as @rjkip said.
I can't reproduce even with goto
commented out, can you try and see if this happens with the default vite template?
i'm experiencing the same behavior than @efreibe first goto() trigger a 'page refresh', subsequent are okay
This is not only happening with goto()
, but with the first click on an <a>
element also.
Only happens a single time (first click/goto
), after that everything works as expected.
I'm also experiencing this issue on <a>
elements as mentioned by @kazzkiq.
Guys, I have the same problem. Lost state for the first time
Good news: Just noticed it only happens on dev server.
I've deployed my application with both adapter-static
and adapter-node
and after build it works as expected (no reloads on first goto()
or <a>
click).
So it seems like this bug happens only on development, no issues with production builds.
Good news: Just noticed it only happens on dev server.
I've deployed my application with both
adapter-static
andadapter-node
and after build it works as expected (no reloads on firstgoto()
or<a>
click).So it seems like this bug happens only on development, no issues with production builds.
I donβt think so!
I have version SvelteKit v1.0.0-next.338 and I still have the state reset for the npm run dev
and npm run preview
commands
Do pages with the same content count as different pages?
For example, there are the following routes: page and page/id
If I go from page /page to /page/id using goto(/page/${id})
then the first time my state is reset.
Subsequent transitions work without resetting the state.
@Rich-Harris i saw you put the need clarification label. How can we help? @efreibe maybe you can put your simple exemple on a repo?
After upgrading my app to the new routing and the lastest sveltkit 1.0.0-next.524, I am seeing this issue.
It only occurs after the node server restarts and then on the first goto, you get a full page refresh. After that, you can load the site on new tabs etc and it works fine until you restart the node server again.
Definitely an initialization issue, maybe Vite related etc... Anyone have a workaround?
More testing and I realized that this only happens when I goto a routeId that is importing a new component.
If I called goto to a routeId that was simple html, no problem. But importing that first component for the first time was causing the reload.
My workaround is to pre cache my main route components before I call goto by just importing them in the main +layout.svelte.
This isn't a bug, it's just how HMR works. If you edit a component, any instances of that component (and their children) will be destroyed and replaced with the new one. State preservation only applies to sibling/parent components β attempting to preserve state within a component that you're editing is a fool's errand, and leads to far more confusing/unwanted behaviour than remounting.
But this issue is about the first goto call after a page reload, with the reload itself being after an HMR change, causing an additional destroy and remount. Why would HMR need to destroy and remount a component that already has the latest changes applied thanks to the page reload?
I just checked and I can reproduce the original issue using a pre 1.0 version of SvelteKit, however, after updating to SvelteKit 1.10.0 (latest at the time of writing), I cannot seem to reproduce the issue. It is possible that the issue has been fixed in one of the newer versions of SvelteKit. As pointed out in the original post, there seems to be some element of luck involved in getting the issue to occur, so I wouldn't say that the issue is definitely fixed.