Skip to content
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

Suspense only renders fallback content on SSR #6023

Closed
1 task done
gijsroge opened this issue Apr 9, 2023 · 3 comments
Closed
1 task done

Suspense only renders fallback content on SSR #6023

gijsroge opened this issue Apr 9, 2023 · 3 comments

Comments

@gijsroge
Copy link

gijsroge commented Apr 9, 2023

What version of Remix are you using?

1.15.0

Are all your remix dependencies & dev-dependencies using the same version?

  • Yes

Steps to Reproduce

  1. clone https://github.com/gijsroge/remix-suspense-issue and run remix
  2. view page source or disable js.

Expected Behavior

I personally think we should see the actual content on server rendering instead of the fallback content.

Next.js does seem to render the actual content on SSR
-> https://stackblitz.com/edit/nextjs-5xhaqa?file=pages%2Findex.js,dynamic-component.js

Actual Behavior

Remix is rendering the Suspense fallback content on the server and when React hydrates, the actual content pops in.

The reason why i'm making this issue is that, if this is the normal behavior this goes agains most of the Remix principles. Suspended content in remix currently means: client side only, bad for seo, popcorn style page loads (jumpy).

Just to give some context as to why i am loading dynamic components on the frontend that should server render.

I'm using Storyblok, and each block in the Storyblok CMS equals a React component in Remix. And for a larger project the amount of blocks in Storyblok can quickly run up to +50, which means 50 react components. If there is no way to server render dynamic components the initial load will contain all the +50 React components.

Might be related to #5763

@minizwergi
Copy link

Same issue using the ClientOnly-Component from remix-utils. Only the fallback component gets rendered on deployed environments but works fine for local development (Deployed using sst.dev)

@lili21
Copy link
Contributor

lili21 commented Apr 11, 2023

I think this is expected behavior, since this's how suspense work.

And what suspense would render depends on the timing that's the lazy import finished. if it finished before the Suspense rendering, then suspense would just render content.

You can try to modify you code like this in your nextjs demo,

import { Suspense, lazy } from 'react';

export default function Home() {
  const Component = lazy(() => {
    return new Promise((resolve) =>
      import('../dynamic-component').then((v) => {
        setTimeout(() => {
          resolve(v);
        }, 2000);
      })
    );
  });
  return (
    <>
      <Suspense fallback={<div>loading...</div>}>
        <Component />
      </Suspense>
    </>
  );
}

and it will always render the fallback.

@jacob-ebey
Copy link
Member

If you lift the lazy() called into the module scope or somewhere it won't be re-initialized every render you should be good to go. Lazy / Suspended components will render on the server and stream to the browser upon resolution if they are inside a suspense boundary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Status: Closed
Development

No branches or pull requests

5 participants