next.js icon indicating copy to clipboard operation
next.js copied to clipboard

AppRouter Suspense not working in Safari on Mac or iOS

Open josephearl opened this issue 2 years ago • 13 comments

Verify canary release

  • [X] I verified that the issue exists in the latest Next.js canary release

Provide environment information

macOS Ventura 13.4.1
Safari Version 16.5.1 (18615.2.9.11.7)

Which area(s) of Next.js are affected? (leave empty if unsure)

App Router

Link to the code that reproduces this issue or a replay of the bug

https://codesandbox.io/p/sandbox/quirky-danilo-nycr3t

To Reproduce

Open the app in Chrome https://nycr3t-3000.csb.app/ Observe that the page is rendered quickly and "Loading car..." is displayed until the car has loaded

Open the app in Safari https://nycr3t-3000.csb.app/ Observe that the page does not render until the car has loaded and never displays the "Loading car..." message

Open the app in mobile Safari on iOS Observe the same behaviour as on Safari on Mac

This seems like the same behaviour as when you just the curl the URL - nothing is loaded until the final HTML

If you make it so that next runs the route dynamically (e.g. add a fetch with { cache: 'no-store' }) and then build and run the app locally in production mode npm run build && npm start the same is observed, so it's not dev server specific

Describe the Bug

Suspense/streaming does not work in Safari

Expected Behaviour

Same behaviour is observed in Chrome as Safari

I'm not sure about to what to expect with curl, I guess the behaviour of not rendering the page until all data is loaded makes sense since curl would not support replace the fallback of course

Which browser are you using? (if relevant)

Safari Version 16.5.1

How are you deploying your application? (if relevant)

No response

josephearl avatar Jul 08 '23 16:07 josephearl

Noticed the same behaviour with Remix in Safari, so probably a React or Safari issue

josephearl avatar Jul 08 '23 18:07 josephearl

Any work arounds?

ardikaveh avatar Jul 10 '23 06:07 ardikaveh

Raised it with React maintainers https://github.com/facebook/react/issues/27089

josephearl avatar Jul 11 '23 10:07 josephearl

This is likely caused by Safari having a minimal chunk size for streaming. If the fallback HTML chunk is too small, Safari might just buffer it without displaying anything.

shuding avatar Jul 12 '23 15:07 shuding

Probably related @shuding https://bugs.webkit.org/show_bug.cgi?id=252413

josephearl avatar Jul 12 '23 15:07 josephearl

Any solution for this? I ran into the same problem and the use of suspense is essential for my use case.

dfiedlerx avatar Aug 25 '23 21:08 dfiedlerx

@dfiedlerx After seeing a lot of comments about the chunk size I tried increasing the size of my loading.tsx file and it works, any file larger than 1Kb works fine. But if loading.tsx is 999 bytes or less the whole page will be blocked until the promise is resolved.

yarikpetrenko avatar Oct 01 '23 08:10 yarikpetrenko

Hi guys any news about this issue or a framework workaround?

luistak avatar Oct 31 '23 17:10 luistak

Hi guys, any news about it?

fillippeprata avatar Nov 27 '23 20:11 fillippeprata

@dfiedlerx After seeing a lot of comments about the chunk size I tried increasing the size of my loading.tsx file and it works, any file larger than 1Kb works fine. But if loading.tsx is 999 bytes or less the whole page will be blocked until the promise is resolved.

how to increase file size?

iycodes avatar Dec 02 '23 18:12 iycodes

@iycodes You just add some text to your file and then to see the actual size you need to build your project and check the size inside build folder. When I was testing I found that comments do nothing, it only works if you add actual payload that will be sent to the client.

yarikpetrenko avatar Dec 03 '23 09:12 yarikpetrenko

Any solution for this except of adding some text to loading component?

palockocz avatar Feb 20 '24 10:02 palockocz

Hi everyone i have solution for fix it, this problem from the Safari can not compile the "this.#" on static file after build project.

I use babel on next.config.ts for fix it

webpack(config) { config.module.rules.push({ test: /\.js$/, loader: 'babel-loader', options: { plugins: [ '@babel/plugin-transform-private-methods', '@babel/plugin-transform-class-properties' ] } }) }

Its babel for help convert to commonjs and can run on Safari webkit all version

thinnakrit avatar Nov 20 '24 11:11 thinnakrit