Tom Fan
Tom Fan

Reputation: 552

Next.js 13: Improve page loading time and display a stable spinner during route changes for a better user experience

I'm working on a Next.js 13 project and facing some issues with slow loading times and an unstable spinner when changing pages.

In my case, when navigating from the home page to the /example page, the behavior is inconsistent:

A. Sometimes, the page changes slowly (about 2-3 seconds), and the /example content is displayed directly without showing the spinner, resulting in a poor user experience.

B. At other times, the route changes immediately, and a spinner is displayed before the /example content, which is the behavior I want to achieve consistently.

I'm using Firebase for fetching data, so optimizing data fetching is not my focus at the moment. Instead, I'm looking to change routes immediately and display a stable spinner to indicate that the content is loading.

How can I improve the page loading time and display a stable spinner to tell user "something is coming"

Here's what I've tried so far:

  1. implement code splitting and dynamic imports to reduce the initial load time.
  2. create a loading.tsx inside /app

Any help or guidance would be greatly appreciated. Thank you!

layout.tsx

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en" suppressHydrationWarning>
      <head />
      <body>
        <AppLayout>
          <MainContainer>{children}</MainContainer>
        </AppLayout>
      </body>
    </html>
  );
}

MainContainer.tsx I also use a Suspense wrap again.

const MainContainer: React.FC<MainContainerProps> = ({ children }) => {
  const color = useColorModeValue(light, dark);

  return (
    <Grid
      templateAreas={`"header""module""footer"`}
      gridTemplateRows={"min-content 1fr min-content"}
      gridTemplateColumns={"1fr"}
      minH="100vh"
      bg={color.background}
      color={color.onBackground}
      outlineColor={color.outline}
    >
      <GridItem area="header" position="sticky" top="0" zIndex={99}>
        <Header />
      </GridItem>
      <GridItem area="module" position="relative" overflow="hidden">
        <Suspense
          fallback={
            <Center minH="calc(100vh - 4rem)">
              <Spinner color={color.primary} />
            </Center>
          }
        >
          {children}
        </Suspense>
      </GridItem>
      <GridItem area="footer">
        <Footer />
      </GridItem>
    </Grid>
  );
};

Upvotes: 3

Views: 1673

Answers (1)

Nihad Abbasov
Nihad Abbasov

Reputation: 1

My friend told me this is because you are currently working on development mode. When you build and deploy, it will work perfectly fast.

And other friend of mine showed me the difference on development and then production, it really was working in a perfect way.

I can't build mine right now to test it, but if you can, suggest you to try it.

Upvotes: 0

Related Questions