To read more articles like this, visit my blog
We all love Next.js. It feels like a supercharged version of React. The nice thing about Next.js is it can render both on the client side and server side.
The idea of server-side rendering is we pre-generate all our pages with the appropriate amount of HTML and CSS and deliver the whole page when requested.
But that comes with a cost!
The problem
The problem is when the user clicks on any route to go to another page, the fetching request must be finished first to be shown to the user.
And the user generally doesn’t know what’s going on because there is no visual clue on the screen.
To solve this problem, we can introduce a nice trick to indicate when it’s loading to the user. And we have two ways to do that.
First Solution
There is a nice library named nextjs-progressbar just to serve this purpose. You can see the result of using this library here
To use this library, first install it
yarn add nextjs-progressbar
Then go inside your _app.tsx
file and import it
import NextNprogress from 'nextjs-progressbar';
Then just render the component along with your <Component />
inside the _app.tsx
. The final result will look something like the following.
import { AppProps } from 'next/app';
import NextNprogress from 'nextjs-progressbar';
function CustomApp({ Component, pageProps }: AppProps) {
return (
<main>
<NextNprogress />
<Component {...pageProps} />
<main/>
);
}
export default CustomApp;
And now you will have a nice loader when you are changing routes.
Problem with the First Solution
This package is built using another nice package that is hugely popular. That is called nprogress .
It just takes away all the complexity from you. But there is a catch. The bundle size of the nprogress
is much, much smaller than nextjs-progressbar
.
So from the comparison, we see that we can save around 14kb if we go with the default library named nprogress
. But it will take a little more effort to get it to work.
Better Solution with Nprogress
Let's install the dependency first
yarn add nprogress
Then go inside your _app.tsx
file and import Nprogress
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
import Router from 'next/router';
Now we are importing the CSS file also. If you want to customize the CSS, you can do that too. Just include the CSS file inside the project itself. It's very minimal. Here is the link to that file
We will also need to import Router
because we have to detect the route changes.
Now we will bind the Nprogress
with our Router
like the following.
Router.events.on('routeChangeStart', (url) => {
console.log(`Loading: ${url}`);
NProgress.start();
});
Router.events.on('routeChangeComplete', () => NProgress.done());
Router.events.on('routeChangeError', () => NProgress.done());
The events are pretty self-explanatory. we are starting Nprogress
when the route change starts. And turning it off when the route change is finished.
Now our _app.tsx
should look something like the following
import { AppProps } from 'next/app';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
import Router from 'next/router';
Router.events.on('routeChangeStart', (url) => {
console.log(`Loading: ${url}`);
NProgress.start();
});
Router.events.on('routeChangeComplete', () => NProgress.done());
Router.events.on('routeChangeError', () => NProgress.done());
function CustomApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
}
export default CustomApp;
This will have the same effect just like before. But this will cause a much less bundle size.
Final Thoughts
There are multiple ways to make your application better. You should always look for ways to improve your application's performance and user experience.
Have something to say? Get in touch with me via LinkedIn or Personal Website