how does Suspense work?
Unanswered
Asiatic Lion posted this in #help-forum
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
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
@Asiatic Lion 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
js
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>;
}
the code, that you shared with the suspense boundary works fine for me. Take a look here: https://codesandbox.io/p/devbox/gifted-ioana-d4jcl3
If you still encounter an unexpected behavior, please create an additional repro example via https://codesandbox.io/
If you still encounter an unexpected behavior, please create an additional repro example via https://codesandbox.io/
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)."
@Asiatic Lion <@484037068239142956> <@301376057326567425> 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)."
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
@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?
edit:ok work when suspense have a very big fallback, not a simple skeleton
there no way to save safari users?
@Asiatic Lion 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?
I am not working with safari, so I cant give you a clear advice, sorry
@Asiatic Lion 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?
not much can be done when it is a browser bug
@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.
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?
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>
);