next.js: getStaticProps with { fallback: true } is very slow when spa routing.

Bug report

Describe the bug

getStaticProps with fallback: true, NextJS send json response to client after calling getStaticProps in server. In my case it takes 2s until the json response comes to browser in vercel production environment in spite of getStatipProps finishing in 100ms. This may be caused by the json response is sent after the ssg rendering in server, I think the json must be returned just after getStatiProps finished.

To Reproduce

  1. Use getStatipProps and getStaticPaths with fallback: true
  2. Request ssg page from browser.
  3. When ssg page loaded, navigate to another dynamic routing page with next/link or next/router.
  4. See the chrome dev tool to see network response.

Expected behavior

The json response returned just after getStaticProps finished in server, and SSG redering and caching is done in server after that.

Screenshots

System information

  • OS: macOS, Vercel server.
  • Browser (if applies): chrome
  • Version of Next.js: 9.4.2
  • Version of Node.js: latest

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 74
  • Comments: 39 (6 by maintainers)

Most upvoted comments

Still the same problem with next 12.0.1 very slow in dev when getStaticPaths is used in a page.

This is still an ongoing issue, any update?

I’m experiencing the same thing as the initial post using {fallback: true}.

Another possible solution might be having an option like Router / Link’s shallow where we can navigate to the fallback page immediately instead of blocking for getStaticProps to finish. That UX seems more inline with the benefits iSSG is designed to provide.

This problem could be alleviated if there was a way to show some loading component while next/link navigating to a fallback: true page (which acts like fallback: blocking). Currently, router.isFallback isn’t true when navigating via next/link to a fallback: true page.

Leaving this comment in case it’s helpful for anyone. I traced the issue down to the styled-icons package.

There appears to be a bug in that package with import paths. TLDR; it was importing all 20k+ icons on every hot reload, route change etc… this was resulting in egregious page load times(20+ seconds) in the dev environment as well as frequent SIGBART crashes.

I’m experiencing this on my site https://civdocs.us (repo: https://github.com/jaredgorski/civdocs.us) with fallback: false. (code reference: https://github.com/jaredgorski/civdocs.us/blob/master/pages/docs/[document]/[section].tsx#L12-L42)

I’m using getStaticProps and getStaticPaths to, hopefully, pre-render the pages at build time, so I should conceivably be getting JAMstack-type performance because everything will be static at runtime, however SPA navigation to these generated pages often pauses anywhere between 1s and 10s before finally navigating.

On https://civdocs.us, you can reproduce by navigating to https://civdocs.us/docs/the-federalist and then clicking one of the links on that page. It’s intermittent, but happens with fair frequency.


Update 2021-03-16 – Could not reproduce on my production project anymore. Did not bother to test locally, but it’s interesting that this issue seems to be solved in production now.

Pro tip that might help some of you out

We got a speedup of around 6 seconds on most of our static pages by doing this!! 🚀

For our application (which is a car company: https://rebil.no) we are using icons from @mui/icons-material. Turns out, when you do named imports, webpack builds the ENTIRE icon library, meaning on every single render you will have to wait for it.

In next.js you can add an option called modularizeImports in next.config.js: https://nextjs.org/docs/advanced-features/compiler#modularize-imports

This will make sure only components you need are actually imported. This goes for all imports, both locally with your own components, and with external packages. In the example below, I’m showing how this works with @mui/icons-material

Example

Before

import { Add } from '@mui/icons-material'; // the INTIRE @mui-icons-material package is built

After

// next.config.js
module.exports = {
  // ... your config here
  modularizeImports: {
    '@mui/material': {
      transform: '@mui/material/{{member}}',
    },
    '@mui/icons-material': {
      transform: '@mui/icons-material/{{member}}',
    },
  },
}

// in component:
import { Add } from '@mui/icons-material'; // Next.js resolves @mui/icons-material/Add for us, meaning that is the only built component!

https://nextjs.org/docs/basic-features/data-fetching#runs-on-every-request-in-development

In development (next dev), getStaticProps will be called on every request

My issue isn’t with dev - my examples are deployed projects in production environments.

Having the same issue. Taking anywhere from 10s - 20s for route changes on SSG pages. We have verified the async data coming in from the CMS is super fast – feel like it’s churning through building ALL of the static pages on every page change…?

I think this also might be the source of my <Link isn’t working as well. Works fine when deployed to site, but in dev mode usually just sits there. Also have getStaticProps and getStaticPaths for building the blog pages…

I too am having this issue. In dev mode it takes extremely long to change route, but it works very quickly when deployed in production mode.

Still the same problem with next 12.0.1 very slow in dev when getStaticPaths is used in a page.

It is slow in dev . But not in Production .

Any news on this? Having the same issue with fallback: true, takes up to 5sec for non generated paths in production.

edit: This issue is from a year ago and I assume it won’t be resolved which is a shame because this feature is pretty much useless now.

Experiencing this a lot in a recent project.

It does look that it does not affect production but this destroys the developer experience on development when using Next.js with fallback mode set to true.

It is far from optimal. On my case, I have getStaticPaths in a [...slug].js dynamic route which means that there is navigation order in the url. To test this flow is close to impossible and I have to refresh the page many times or wait for the next page to render properly which can be quite some seconds.

Any idea when this might be picked up? I see that this is already tagged by Vercel team but not sure if will be picked up any time soon.

Can you provide a repository to reproduce?