SSR+Suspense: the fallback slot is not hidden after hydration
Vue version
3.2.45
Link to minimal reproduction
https://github.com/Alexis2004/vue-ssr-suspense-fallback-issue or https://sfc.vuejs.org/#__DEV____SSR__eNqVU01vm0AQ/SvT7QEs2WClzcUlVqr00lulVj1x2cDYpYFZtLvYtSz+e2eXj4CTuooPFsO8eTPz5nEWn+s6OjQoNiKxWNWltLhNCSDJi4N/APhyIlkVGWRlgWRBUXmCgywb3EBirFa0357PkHeony4BbZvEfcqTxQPbhDb53pgaySDYokLV2LtUrFPRZzk/zAPvc9zJprRjipMPiqybJn7Gx7MFLih2siwfZfY05XiepfsNnKWSeUH7KIom4HGFV3sl8bDNbOEZjkOT6aJ2exRVrbQFlg13BeGD4pi49xI07qCFnVYVBHyYYMQO03WpKO5jdz0GpYR/PKzX6pI4PLu5+ER8tYCPHixdnA1pswEPGEXw6db/G7RNHS4GQKbIMP303Hdu6jAgpgoWnzoYV/3o7hpy7d12KIdZaeSNxASBfwj64nYJt+u1o+pizSNoep3Cz8glvrRNqV043XulxVJ08q0qWUe/jSJ2uqdJ+4RJxbh7KlhMF6fil7W12cRxQ/XTPmKd4nvOxboh59ZVrqr7D9FN9PGWL23s9H2Eplo9anU0qLljKvoBPXnMLw+oVxopR436arML7KzhRe5F00EMFmBilGuf+degcrd10Hf/9zCUkvb8xTr9rvh5ZmV/zjfYtB+8s6o0J8ouvSiPsrBAeIRv3KUwGIYajSoPOLfcCzP2qLBh+dwA+WIJN+vOct5N//JebzMeyUNGo6Uk2r8aML9O
Steps to reproduce
Open the prepared sfc.vuejs.org link
or
Clone prepared github-repo, run yarn install && yarn dev
and open http://localhost:3000 URL in the browser
What is expected?
Application root component will be rendered on the server to:
Dynamic client only value: value
I'm content!
and will not change after client hydration.
What is actually happening?
Application root component rendering on the server to:
Dynamic client only value: value
I'm content!
and then replaced on client during hydration with:
Dynamic client only value: value
I'm content!
Content loading...
As you can see Suspense
's fallback slot content for some reason it still shows up.
System Info
System:
OS: macOS 13.0.1
CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
Memory: 1.19 GB / 32.00 GB
Shell: 5.9 - /usr/local/bin/zsh
Binaries:
Node: 16.17.1 - /usr/local/opt/node@16/bin/node
Yarn: 1.22.17 - /usr/local/bin/yarn
npm: 8.15.0 - /usr/local/opt/node@16/bin/npm
Browsers:
Chrome: 107.0.5304.110
Firefox: 106.0.5
Safari: 16.1
Any additional comments?
Client only rendering (if not html markup provided from SSR) works as expected. SSR rendering also works as expected. The only appears during client hydration.
An important condition for reproducing the bug is the presence of a
dynamicValue
reactive variable that changes the root component template (located outside theSuspension
tag).
In my project, the variable affects the name of the class that I add to the container depending on the width of the current window, but for the example, I replaced this with displaying the value of the variable in the template, and I change the variable itself inside setTimeout
.
If you comment out line dynamicValue.value = 'value';
then the hydration starts working as expected.
It will be fixed in https://github.com/vuejs/core/pull/7188 such as: playground
@liulinboyi There seems to be a problem with the SSR in the online playground, warning node mismatch.
@edison1105, as I see it, the mismatch issue is only reproducible in the playground environment. In the playground there is a mismatch warning both before and after the fix. If you reproduce and issue on the local machine then there is no mismatch on the current stable version of VueJS.
As I understand that suspense
in SSR should solve the following problems:
- Fetch everything before showing anything
- Load everything before hydrating anything
- Hydrate everything before interacting with anything
Using the above example
suspense
doesn't solve the problem that data is fetched for the entire application on the server, every thing is blocked till data is fetched.