core icon indicating copy to clipboard operation
core copied to clipboard

SSR+Suspense: the fallback slot is not hidden after hydration

Open Alexis2004 opened this issue 3 years ago • 3 comments

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?

  1. 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.

  2. An important condition for reproducing the bug is the presence of a dynamicValue reactive variable that changes the root component template (located outside the Suspension 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.

Alexis2004 avatar Nov 19 '22 13:11 Alexis2004

It will be fixed in https://github.com/vuejs/core/pull/7188 such as: playground

liulinboyi avatar Nov 23 '22 02:11 liulinboyi

@liulinboyi There seems to be a problem with the SSR in the online playground, warning node mismatch.

edison1105 avatar Nov 23 '22 02:11 edison1105

@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.

Alexis2004 avatar Nov 28 '22 16:11 Alexis2004

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.

hassan715 avatar Feb 28 '23 19:02 hassan715