apal21 / nextjs-progressbar

A simple Next.js progressbar component using NProgress.

Home Page:https://www.npmjs.com/package/nextjs-progressbar

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Progress never finishes on Static Generation

rbsmidt opened this issue · comments

Hi

I've used this module in a couple of projects, and enjoy it generally! Thanks so much.

However I've come across some (seemingly) unexpected behaviour for Next JS projects utilising getStaticProps and fallback: 'block' in getStaticPaths as re-generation strategy. It seems when hitting a page, that needs some background generation, that the progress bar never finishes entirely. Usually hangs with approx 10% or 5% left. While the page in question is fully operational, and all, I've noticed users and clients interpret it as slow loading speed and bad performance. If you refresh the browser while the last 5-10% is missing, it reloads instantly and the progress bar also run all the way through.
Is this something that can be handled with options on the component, is it expected behaviour, and just not the best fit for SSG/ISG Next JS applications or something else?

In order to reproduce. Test in Next JS project with static site generation and dynamic paths and use NextNProgress in app.js. My options is this:

<NextNProgress color="#676767" options={{ showSpinner: false }} />

I'm facing the same problem. Did you find a workaround?

commented

For me the issue occured when the route change is happen immediately after a react rerender.

So, imagine a login page where the user clicks on a login button (step 1), gets authenticated (step 2) and then redirected (step 3) to a dashboard page.
The progressbar will keep loading forever because step 2 updates the UI (e.g. user name now showing in the navbar) and the page change is triggered right after. In this way, somehow the navigation and the render get mixed.

Not working:

   const handleLogin = useCallback((e) => {
        e.preventDefault();
        logIn(email, password, keepLoggedIn).then(() => {
            router.push("/dashboard").then() //immediately executed once logIn finishes
        }).catch((error) => {
            setError('email or password not correct')
        });
    }, [email, password, keepLoggedIn])

It works if the route change is added to the end of the event queue, i.e. setting a timeout:

const handleLogin = useCallback((e) => {
        e.preventDefault();
        logIn(email, password, keepLoggedIn).then(() => {
            setTimeout(() => {
                router.push("/dashboard").then() //now executed as soon as the rerender finished
            }, 0)
        }).catch((error) => {
                setError('email or password not correct')
            });
    }, [email, password, keepLoggedIn])

is there any solution yet for this issue?

It works for me with nprogress:

import { useStyle } from "src/v2/theme";
import NextProgressLine from "next-progress";
import { useRouter } from "next/router";
import { useEffect } from "react";
import NProgress from "nprogress";

export const NextProgress = () => {
  const [, theme] = useStyle();
  const router = useRouter();

  useEffect(() => {
    //This is fix for it https://github.com/apal21/nextjs-progressbar/issues/77
    //When we start to change the route we start the progress bar and when the route change is done we stop it
    NProgress.done();
  }, [router.route]);

  return (
    <NextProgressLine
      delay={500}
      disableSameRoute
      height={3}
      options={{
        easing: "ease",
        speed: 1000,
        showSpinner: false,
      }}
      color={theme.figmaColors.darkPrimary}
    />
  );
};

I'll try it out