Next.js Discord

Discord Forum

Suspense fires late

Answered
Spinge Bib Sqorpnts posted this in #help-forum
Open in Discord
Hello! I have a Next.js application that uses suspense to wait for page load, but instead, when switching URLs it first shows the webpage, then shows and quickly hides the suspense fallback.

I'm unsure if I have a flawed knowledge of Suspense in Next or is some other part of my code screwing things up.
next info:
Operating System:        
  Platform: win32        
  Arch: x64
  Version: Windows 10 Pro
Binaries:
  Node: 18.17.1
  npm: N/A
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 13.5.3
  eslint-config-next: 13.5.3
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.2.2
Next.js Config:
  output: N/A


package.json
"dependencies": {
  "@emotion/cache": "^11.11.0",
  "@emotion/react": "^11.11.1",
  "@emotion/styled": "^11.11.0",
  "@mui/icons-material": "^5.14.9",
  "@mui/material": "^5.14.10",
  "@mui/x-date-pickers": "^6.14.0",
  "@next/bundle-analyzer": "^13.5.2",
  "dayjs": "^1.11.10",
  "lodash": "^4.17.21",
  "next": "13.5.4-canary.0",
  "next-intl": "3.0.0-beta.18",
  "overlayscrollbars": "^2.3.1",
  "overlayscrollbars-react": "^0.5.2",
  "react": "^18.2.0",
  "react-dom": "^18.2.0",
  "react-signature-canvas": "^1.0.6",
  "stylis": "^4.3.0",
  "stylis-plugin-rtl": "^2.1.1",
  "sweetalert2": "^11.7.28",
  "sweetalert2-react-content": "^5.0.7"
},
"devDependencies": {
  "@trivago/prettier-plugin-sort-imports": "^4.2.0",
  "@types/lodash": "^4.14.198",
  "@types/node": "^20.6.3",
  "@types/react": "18.2.22",
  "@types/react-dom": "18.2.7",
  "@types/react-signature-canvas": "^1.0.2",
  "@types/stylis": "^4.2.0",
  "@typescript-eslint/eslint-plugin": "^6.7.2",
  "@typescript-eslint/parser": "^6.7.2",
  "autoprefixer": "10.4.16",
  "eslint": "^8.49.0",
  "eslint-config-next": "13.5.3",
  "eslint-config-prettier": "^9.0.0",
  "eslint-plugin-prettier": "^5.0.0",
  "npm-check": "^6.0.1",
  "postcss": "^8.4.30",
  "prettier": "3.0.3",
  "sass": "^1.68.0",
  "tailwindcss": "3.3.3",
  "typescript": "5.2.2"
}
Answered by Spinge Bib Sqorpnts
@alfonsus ardani React.lazy() in some components further down the tree caused the double-trigger
View full answer

50 Replies

I've already attempted using the Canary release, 13.5.4-canary.0, to no avail
ure saying theres a slight delay/fkick where the fallback doesn't get rendered during suspense?
@alfonsus ardani ure saying theres a slight delay/fkick where the fallback doesn't get rendered during suspense?
When I go to a URL, it shows the 'full' webpage, flashes the fallback and then shows the webpage again
does it happen on prod
also is this <Suspense> or loading.tsx?
@alfonsus ardani does it happen on prod
It did, but i'll try again incase there was a one-off or just human error
okay
seems like a weird routing issue, can you try reproducing it in a new project? using the latest canary version
Sure, I'll try that. I'll also record a short video in-case we're not on the same page on what's happening
@alfonsus ardani does it happen on prod
Still happens, not as noticable though
@alfonsus ardani
(hid the top of the scren because of some sensitive info, but its just me typing in different urls)
you know you are already tagging me when you reply xD no need to tag again
Didn't mean to double ping
@alfonsus ardani seems like a weird routing issue, can you try reproducing it in a new project? using the latest canary version
Now it doesn't show up, but I think that my code is flawed...
layout.tsx
const FetchData = async () => {
  const d = await fetch('https://restcountries.com/v3.1/all', { next: { revalidate: 0 } });
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(d.json());
    }, 3000);
  });
};

export default async function RootLayout({ children }: { children: React.ReactNode }) {
  const d = await FetchData();
  return (
    <html lang="en">
      <body className={inter.className}>{children}</body>
    </html>
  );
}
uhhhh
it shouldnt show up if you havent made loading.tsx
It's a simple spinner there so I didn't think I'd have to add it here
i think the loading is only for child layout coponent
like the boundaries goes as follows

Layou -> Error -> Suspense -> Page

so if you make loading.tsx its only for child awaits like /page.tsx or /child/layout.tsx or /child/page.tsx
@alfonsus ardani i think the loading is only for child layout coponent
That's right, but in the original project the layout is also on a child route
aka not the root layout
@alfonsus ardani hmm can i see the file structure for this new project
original project if relevant
@alfonsus ardani i mean preferrably the `await` shouldn't be here but on the child layout/page instead
it is, I moved it after you said I should try it on the child layout
@Spinge Bib Sqorpnts original project if relevant
Here its the app/[mof]/forms/161/layout.tsx
@alfonsus ardani see if that worked
also, in the OG project, after adding a timeout to the fetch request, something causes the loading.tsx to show up again and I have no idea what it is
is there any way to see what causes the loading.tsx to show up?
its the async/await of server components.
I wonder if it's nested lazy() loaded components...
those causes the loading.tsx to show up
@alfonsus ardani those causes the loading.tsx to show up
the first time is okay, but what causes it to show up for the second time
im not sure either why it would get triggered twice
ill try removing all lazy references in the OG
@alfonsus ardani React.lazy() in some components further down the tree caused the double-trigger
Answer
yeah
ive never used that
That's fair
thank you for your help though :D
have a great day
@alfonsus ardani can you reproduce this? is this confirmed?
well, removing lazy() in the OG project fixed the issue
I'd like to add that using next/dynamic works, unlike React.lazy