I have a website built in React Js and the same one on Next Js as well.
The problem which I am facing right now is, the router seems very slow in the nextJs compare to react-router-dom, It's taking almost 2-3 seconds to change the route.
Here are the URLs where you can feel the difference between the performance by moving around different pages.
(React Router Dom) vs (NextJs)
I had read some comments on Github where few experts are saying that It will resolve in production. but It looks same in production too.
Please have a look at the following code
_app.jsx
// import App from 'next/app'
import React from "react"
import Router from 'next/router';
import "../static/sass/application.scss";
import "bootstrap/dist/css/bootstrap.min.css";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import 'semantic-ui-css/semantic.min.css'
import { wrapper } from "../../redux/utils/store"
import App from 'next/app';
// A simple component that we created
import {LoaderOverlay} from '../components/Reusable'
class MyApp extends App {
constructor(props){
super(props)
this.state = {
isLoading: false,
}
Router.onRouteChangeStart = (url) => {
// Some page has started loading
this.setState({
isLoading: true,
}) // set state to pass to loader prop
};
Router.onRouteChangeComplete = (url) => {
// Some page has finished loading
this.setState({
isLoading: false,
}) // set state to pass to loader prop
};
Router.onRouteChangeError = (err, url) => {
this.setState({isLoading: false,})
};
};
render() {
const {Component, pageProps} = this.props
return (
<div>
{this.state.isLoading ? (
<LoaderOverlay/>
) : (
<Component {...pageProps} />
)}
</div>
)
}
}
export default wrapper.withRedux(MyApp);
_document.jsx
import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
static async getInitialProps(ctx) {
const originalRenderPage = ctx.renderPage
ctx.renderPage = () =>
originalRenderPage({
// useful for wrapping the whole react tree
enhanceApp: (App) => App,
// useful for wrapping in a per-page basis
enhanceComponent: (Component) => Component,
})
// Run the parent `getInitialProps`, it now includes the custom `renderPage`
const initialProps = await Document.getInitialProps(ctx)
return initialProps
}
render() {
return (
<Html lang="en">
<Head>
<link async rel="stylesheet" href="//cdn.jsdelivr/npm/[email protected]/dist/semantic.min.css"/>
</Head>
<body>
<div className={'main-wrapper'}>
<Main />
</div>
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
I have a website built in React Js and the same one on Next Js as well.
The problem which I am facing right now is, the router seems very slow in the nextJs compare to react-router-dom, It's taking almost 2-3 seconds to change the route.
Here are the URLs where you can feel the difference between the performance by moving around different pages.
https://cutt.ly/mhbPkOE (React Router Dom) vs https://cutt.ly/BhbPvHv (NextJs)
I had read some comments on Github where few experts are saying that It will resolve in production. but It looks same in production too.
Please have a look at the following code
_app.jsx
// import App from 'next/app'
import React from "react"
import Router from 'next/router';
import "../static/sass/application.scss";
import "bootstrap/dist/css/bootstrap.min.css";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import 'semantic-ui-css/semantic.min.css'
import { wrapper } from "../../redux/utils/store"
import App from 'next/app';
// A simple component that we created
import {LoaderOverlay} from '../components/Reusable'
class MyApp extends App {
constructor(props){
super(props)
this.state = {
isLoading: false,
}
Router.onRouteChangeStart = (url) => {
// Some page has started loading
this.setState({
isLoading: true,
}) // set state to pass to loader prop
};
Router.onRouteChangeComplete = (url) => {
// Some page has finished loading
this.setState({
isLoading: false,
}) // set state to pass to loader prop
};
Router.onRouteChangeError = (err, url) => {
this.setState({isLoading: false,})
};
};
render() {
const {Component, pageProps} = this.props
return (
<div>
{this.state.isLoading ? (
<LoaderOverlay/>
) : (
<Component {...pageProps} />
)}
</div>
)
}
}
export default wrapper.withRedux(MyApp);
_document.jsx
import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
static async getInitialProps(ctx) {
const originalRenderPage = ctx.renderPage
ctx.renderPage = () =>
originalRenderPage({
// useful for wrapping the whole react tree
enhanceApp: (App) => App,
// useful for wrapping in a per-page basis
enhanceComponent: (Component) => Component,
})
// Run the parent `getInitialProps`, it now includes the custom `renderPage`
const initialProps = await Document.getInitialProps(ctx)
return initialProps
}
render() {
return (
<Html lang="en">
<Head>
<link async rel="stylesheet" href="//cdn.jsdelivr.net/npm/[email protected]/dist/semantic.min.css"/>
</Head>
<body>
<div className={'main-wrapper'}>
<Main />
</div>
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
Share
Improve this question
edited Mar 7, 2022 at 8:48
juliomalves
50.3k23 gold badges177 silver badges168 bronze badges
asked Dec 4, 2020 at 16:07
Muhammad OwaisMuhammad Owais
1,1863 gold badges19 silver badges40 bronze badges
3
|
5 Answers
Reset to default 12Development mode (next dev
) is much slower because the routes aren't pre-built.
All delay related to routing assuming you don't have any server side blocking data requirements via getInitialProps, getServerSideProps, should not be present when running production mode with next build
followed by next start
.
I had the same issue. And I managed to speed things up a bit by doing the following
- I had a fetch requests directly on the page so I guess the server has to do the fetching before rendering the UI so it takes time for the initial load.
- I moved this request to another server component and imported it in the page component
- I did this for any other places in other pages as well.
- I implemented react suspense. So in the initial load, page component has something to render.
This way I managed to reduce the page load time, which helped me to reduce the time between moving between pages.
So in summary my idea was to render what is available as soon as possible and render the components that are associated with API calls later. until they fetch the data, I showed a skeleton with the help of react suspense
Not sure if you have found a fix for this yet, but I came across this article about "shallow routing". I can't see much improvement in my application when using it, but maybe it will help someone else:
https://nextjs.org/docs/routing/shallow-routing
Hey I think you are in your production mode. That's why it is slow. But if you will host your site it will be pretty much like react only. But then also if you want to routing fast Then npm i [email protected] --save will work fine..
to solve this issue followed the commands:
- yarn build/nmp build
- yarn start/npm start
I hope this will solve this issue
shallow
prop on all theLink
s. Somehow, still, in production, my cards are taking anywhere from 300ms to 2s to open in a modal. If I use React useState to track the opened card instead of the router, the opening takes 50ms – Art Ginzburg Commented May 24, 2023 at 8:32