Next.js Discord

Discord Forum

how does Suspense work?

Unanswered
Asiatic Lion posted this in #help-forum
Open in Discord
Asiatic LionOP
I tried to make some test as React official documentation but can't see any loading state
my entire page is blocked for 10s

this my test/page.tsx
import { Suspense } from "react";
export default function Test() {
  return (
    <div>
      <Suspense fallback={<p>loadding</p>}>
        <Component></Component>
      </Suspense>
    </div>
  );
}

function waitForSeconds(seconds: number) {
  return new Promise((resolve) => {
    setTimeout(resolve, seconds * 1000);
  });
}
export async function Component() {
  await waitForSeconds(10);
  return <div className="h-10 w-10 bg-red-400"></div>;
}

16 Replies

By the way, if I recall correctly, safari has a weird bug where if you send a fallback that is too small, safari might disregard it and wait for the whole page.
Asiatic LionOP
@joulev @B33fb0n3 Wow, I never thought that it was a Safari bug. I am a heavy Safari user. Is there any approach to solve it? I have tried on mobile and got "Application error: a client-side exception has occurred (see the browser console for more information)."
@B33fb0n3 you can provide data inside the wait method (maybe even large data). That would be the easiest way. Or you can try it on desktop with a diffrent browser
Asiatic LionOP
can't make it work even with a large data
edit:ok work when suspense have a very big fallback, not a simple skeleton
there no way to save safari users?
@Asiatic Lion solved?
@B33fb0n3 <@1055820782015623209> solved?
Asiatic LionOP
No,I gave up, no ideas how to resolve…
@Asiatic Lion No,I gave up, no ideas how to resolve…
oh I am sorry.... can I help u in any way (not for the browser bug)
@B33fb0n3 oh I am sorry.... can I help u in any way (not for the browser bug)
Asiatic LionOP
Thank you so much ,for now I just avoid using suspense
Kind of a bad choice imo to make chromium/firefox users suffer at no benefits. Avoiding Suspense doesn’t make it any more pleasant for all users regardless of browser they use.

You should instead do both of these:
* Use a loading screen that works with safari. Loading screens with skeleton elements are likely to meet the size threshold and are also better UX-wise.
* Reduce loading time. Really, 10s loading time is a terrible number unless you are loading a browser game or something. Then even safari users don’t get to suffer too much.
@joulev Kind of a bad choice imo to make chromium/firefox users suffer at *no* benefits. Avoiding Suspense doesn’t make it any more pleasant for all users regardless of browser they use. You should instead do both of these: * Use a loading screen that works with safari. Loading screens with skeleton elements are likely to meet the size threshold and are also better UX-wise. * Reduce loading time. Really, 10s loading time is a terrible number unless you are loading a browser game or something. Then even safari users don’t get to suffer too much.
Asiatic LionOP
did you mean to remplace Suspense with useEffect+useState?
samething like this example?
// MyPage.js
import { useEffect, useState } from 'react';
import SkeletonLoader from './SkeletonLoader';

const MyPage = () => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
      fetch('/api/data')
        .then(response => response.json())
        .then(data => {
          setData(data);
          setLoading(false);
        });
    ); 
  }, []);

  if (loading) {
    return <SkeletonLoader />;
  }

  return (
    <div>
      <h1>{data.title}</h1>
      <p>{data.content}</p>
    </div>
  );
};

export default MyPage;
Asiatic LionOP
As Suspense does not work with Safari, loading.js (edit:smaller than 1kb) does not work either. It’s a pity, as I really like this feature.
German Spaniel
Yeah! That's bad; I've the same issue. Doesn't work also on iOS.
German Spaniel
I did that and it works.


const SafariFallbackSizeFix = () => (
  <div>{Array(1000).fill('\u200C\u200D').join('')}</div>
);