next.js: NextJs compiling extremely slow
What version of Next.js are you using?
11.1.2
What version of Node.js are you using?
14.18.0
What browser are you using?
Chrome
What operating system are you using?
Windows 10
How are you deploying your application?
AWS ECS
Describe the Bug
I’ve been using NextJs for years and recently it has been very hard to work with because very slow in development.
After npm run dev
, I go to localhost:3000
. From there the page can take up to 60 seconds to display. Then when the first page finally displays, each code change fast refresh or page transition SSR (compilation) takes between 15-20 seconds, sometimes more than 30 seconds, and sometimes it even doesn’t work so I have to refresh the page.
- I read that on windows, windows defender could be blocking so I did this, which didn’t help: https://github.com/vercel/next.js/issues/12797#issuecomment-660225689
- I use webpack 5
- I read tailwind could be causing this kind of issue, but I don’t use it.
Expected Behavior
Page load + compilation should be faster.
To Reproduce
Unfortunately, I cannot send a reproducible UI because the project I work on is pretty big and the UI is under NDA.
Maybe without a reproducible UI, you guys have thoughts about how to improve/fix the compilation time on windows. Maybe some of you have faced the same problem and fixed it somehow. I’m all ears.
My package.json
{ “name”: “myname”, “version”: “0.1.0”, “private”: true, “scripts”: { “dev”: “next dev”, “build”: “next build”, “start”: “next start -p 3002” }, “dependencies”: { “@react-google-maps/api”: “^2.0.2”, “@sentry/browser”: “^6.7.2”, “@sentry/react”: “^6.7.2”, “@sentry/tracing”: “^6.7.2”, “@sentry/webpack-plugin”: “^1.15.1”, “@stripe/react-stripe-js”: “^1.4.0”, “@stripe/stripe-js”: “^1.13.1”, “accept-language-parser”: “^1.5.0”, “aws-sdk”: “^2.802.0”, “base-64”: “^1.0.0”, “cors”: “^2.8.5”, “dotenv”: “^8.2.0”, “hls.js”: “^0.14.16”, “iban”: “0.0.14”, “js-sha256”: “^0.9.0”, “libphonenumber-js”: “^1.9.11”, “localized-countries”: “^2.0.0”, “lodash”: “^4.17.21”, “moment”: “^2.29.1”, “next”: “^11.1.2”, “next-compose-plugins”: “^2.2.1”, “next-fonts”: “^1.5.1”, “next-images”: “^1.8.1”, “next-seo”: “^4.17.0”, “nookies”: “^2.5.0”, “platform”: “^1.3.6”, “qrcode”: “^1.4.4”, “randomstring”: “^1.1.5”, “react”: “^17.0.2”, “react-cropper”: “^2.1.4”, “react-datepicker”: “^3.3.0”, “react-device-detect”: “^1.15.0”, “react-dom”: “^17.0.2”, “react-dotdotdot”: “^1.3.1”, “react-ga”: “^3.3.0”, “react-geocode”: “^0.2.2”, “react-google-maps”: “^9.4.5”, “react-lines-ellipsis”: “^0.14.1”, “react-loading-skeleton”: “^2.2.0”, “react-query”: “^3.13.2”, “react-textarea-autosize”: “^8.3.2”, “sass”: “^1.29.0”, “stripe”: “^8.137.0”, “uuid”: “^8.3.1”, “video.js”: “^7.11.0”, “videojs-contrib-dash”: “^4.0.0” }, “devDependencies”: { “@svgr/webpack”: “^5.5.0” } }
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 18
- Comments: 64 (19 by maintainers)
I’ve experienced the issue with
@mui/material
and my own npm package@gorazdo/tomui
The problem comes from a lot of modules to process (11k) like in this article Unfortunately, this solution doesn’t work. The problem is the regex (which is a completely mysterious thing for a non-rust developer. I’ve even tried Rust Regex online tool ), with no luck.My Solution (3-5 times faster)
I’ve managed it using the following config:
But I had to update imports manually for
useTheme
,ThemeProvider
,styled
,lighten
anddarken
in my casefrom:
to
To fix my library I had to use
default export
for each file which is going to be modularized.Questions
@mui/material
?Experiencing this issue?
To provide a trace which only includes metadata of the application:
npm install next@canary
(oryarn add next@canary
)ctrl + c
).next/trace
file here or send it to https://twitter.com/timneutkens if you don’t want to share it publicly. You can use https://gist.github.com to create a private url for the file. - If you have a custom.babelrc
please provide it - If you have a customnext.config.js
please provide it - if you are using TailwindCSS please providetailwind.config.js
⚠️ The metadata in
.next/trace
includes full file paths to all JS/CSS. It does not include the file contents. ⚠️ The main thing we need to help investigate your application is.next/trace
, package.json and such are not helpful in investigating the issue.Reply to earlier messages
So far all I’ve done is help investigate the slowdowns for the people that reached out. There’s no specific solution as it highly depends on the app and I’m going to share the findings. . I’ve been working on a way that we can investigate these slowdowns without needing the application code itself but it requires a bunch of steps that up till a few days ago were quite involved.
Here’s a list of what I’ve found so far:
http://localhost:3000/about
Next.js will at that point start compiling the JS/CSS forpages/about.js
, this is intentional to ensure that you can have thousands of pages in a Next.js app and it would not slow down your app, otherwise you’d pay this compilation penalty at bootupfs.readFile
seems to be slow, it takes over 100ms per file, we expanded the tracing to include timing for individual filespages/index.js
reads and compiles about 6867 files. What I’ve found is that 5557 of those are coming from@material-ui/icons/esm
, assuming that the app is not using 5.5K icons I’d recommend changing how they are imported so that not all files have to be compiled. Based on debugging this trace we’re adding a separate chart that will allow us to visualize the dependency graph based on a trace fileI had a similar issue and it was also due to
@material-ui/icons
and loading all of them. If you import them directly from your application code, the tree-shaking works properly. However, in our case, we were importing them from an internal package installed in thenode_modules
of our application which resulted in all icons being imported (only in the server bundle).We solved it by following this documentation and adding a babel plugin to automatically rename our named imports to default imports when building and publishing our internal package.
I’ve added the
modularizeImports
MUI transforms and tried 10 other things mentioned in other places, but still the DX with NextJS is very bad for many people due to extremely slow page loads. The DX in other tools in the ecosystem (e.g. vite, even create-react-app) don’t suffer from this, so I don’t think this issue should be closed.The development experience with NextJS is advertised greatly by Vercel, so it is frustrating when it does not live up to its promises.
This is how the compiling look like during a page navigation in my fairly large project:
Here’s some screenshots when I tried adding dependencies one by one in a new project with next
13.1.6
:After adding
date-fns
:After adding
modularizeImport
ondate-fns
:So the
modularizeImports
definitely works, but only a small number of libraries organizes their imports in a way that is compatible.After adding
@mui/x-data-grid
(@mui/material
,@mui/icons-material
,date-fns
,@mui/x-data-grid
in total)With ~1400 modules compiled and taking 1.7 seconds for page load in an empty project just by adding a few dependencies, it’s easy to see how it gets out of hand in a large project.
I wonder if a lot of the slow page loading is due to prefetching of pages? In the following screenshot I hovered my mouse over a few links in my sidebar before navigating which seems to create a waterfall effect and cause delay.
If NextJS cannot improve the page load performance due to Webpack, I still think it can help with tooling to improve the DX. For example:
modularizeImport
and do it automatically …etcHappy to share private repo with NextJS developers if it helps solving this issue.
Our app www.drive.com.au is the largest automotive site in Australia.
Creating a production build with
next build
takes > 20 minutes on a machine with 6 cores and 32 GB of RAM. Our builds have slowed significantly since updating to Next 11.x@timneutkens - Happy to provide access to config and code, if its of wider benefit to the community, we are also happy to pitch in if helpful.
Issue template
What version of Next.js are you using?
11.1.2
What version of Node.js are you using?
14.18.0
What browser are you using?
Chrome
What operating system are you using?
Mac OS 11.6 (Big Sur)
How are you deploying your application?
AWS ECS
Describe the Bug
We use
getServerSideProps
for > 90% of pages.We’ve tried:
.next
folder)babel
,postcss
,tailwind
etc.I admire you helping one to one, but shouldn’t the potential solutions be posted here to help everyone that has this issue?
Good news! I approximately reduced my
next dev
from 6500 to 2500 modules for the first page I load!TLDR: explode your imports!
For the long story:
I tried at first
babel-plugin-import
(https://github.com/inclusion-numerique/mediature/commit/a5dc625fdd072c43438cf70f60f420201e80d62d) to allow using merged imports for MUI… but it didn’t reduce the modules built.Then I tried the way of Next.js with:
But nothing changed too.
Weeks after I was just upset by this painful slow compilation of module just to load basic pages (sometimes 40 seconds).
I decided to go the hard way, I replaced for example all my:
by:
I also replaced for example:
by:
by:
(for my examples it was spread across files but I tried to give you an overview of the steps (https://github.com/inclusion-numerique/mediature/commit/f1c4850da4427de2e369931d0ede7bc5ba81b4aa), just think about big librairies and try to see if there is way to do the “tree-shaking” manually).
Note that I don’t get why using Babel or Next.js optimization didn’t help on MUI. From what I read Webpack tree-shaking is only enabled when
NODE_ENV=production
, is it the reason? For me tree-shaking is also important in development to not bring everything to the table of compilation.If Babel/Next.js optimizations worked for you even with
next dev
, I’m fine to admit I did something wrong, but no clue what it is. Is it possible it’s due topnpm
? (just asking, I saw a lot of weird issues with it due to symlinks)Speaking of
pnpm
, I also find a way to save some modules compilation (due to duplication of packages). I use a monorepo and some of my packages are using MUI. Since they were not align on some rules ofpnpm
a dependency with the exact same version in 2 packages would not be merged into one (it’s deduplicated). It’s more specific topnpm
so if you want this, I tried to explain a bit how to debug/fix this: https://github.com/pnpm/pnpm/discussions/6055#discussioncomment-5018827Now my first load of a page is 2500 modules in about 12 seconds, which is way better even if still not perfect.
Hope this helps!
In case it helps somebody, in our case the line causing the extremely slow compilation was this one:
In our case we are using turborepo and when adding the package/ui the compilation time goes from 2-5 seconds to >500 seconds
Is there a public tool available to parse the.next/trace
file? Would love to dive deeper without bugging Tim 😃Edit: https://github.com/vercel/next.js/blob/canary/scripts/trace-to-tree.mjs is the tool (and it’s awesome!)
fixed it for me, thanks!
Hey Steven, could you send me a message on https://twitter.com/timneutkens, then we can investigate it without code access.
I’ve had the same problem for the last 8 months. It seems many people are having the same problem. In my opinion this should be a priority to get fixed. I have tried almost everything: deactivating windows defender, using yarn instead of npm, but nothing has worked.
sometimes it takes 1 min to change pages in development. In production it’s super fast.
I can’t publish my code as well since it’s copyrighted.
here are my dependencies
Hi. but, how you found workaround to not include paths from one of packages if you really need this?
hello there, to fix you problem you have to make a component (put all you code here like the “App” component in react) and then put it like this : import App from ‘./App’ export default function Home() { // return the App component } update just the App
You can visualize the trace yourself using canary/scripts/trace-to-tree.mjs if you’re curious.
Prefetching is disabled in development for
pages
. Forapp
it’s enabled but only on hover. If you want to completely disable prefetching you can passprefetch={false}
.See above.
This is potentially breaking which is why we don’t have a default config.
Overall the issues with large amounts of modules was one the reasons we started building Turbopack: https://turbo.build/pack. Which is currently in alpha. It’s a completely new architecture to allow processing many more modules quickly, including for
next build
.“dev”: “next dev --turbo”, using turbopack worked for me https://nextjs.org/docs/architecture/turbopack
THIS!!! Thank you sir, this solved a huge headache for me. I copied my settings from some example config provided by turbo I believe and this was a nightmare.
@Vallo not without changing it, I also had to do the same for a library I was using.
Enabling swcMinify might speed things up.
Is there a way to lazily compile linked pages in the background once the current page is done?
Hey @ctotheameron, I had a look at the trace file and it seems that the slowdown is coming from vanilla-extract. If you have a look at the output of our trace file interpreter: https://gist.github.com/timneutkens/52f5cf1d1991b2789fbaa81885638c00 (you can run it yourself, it’s this script: https://github.com/vercel/next.js/blob/canary/scripts/trace-to-tree.mjs)
It seems the large majority of the time spent is caused by the plugin added: https://gist.github.com/ctotheameron/4737a779386aac592d3f7fde13016d83#file-next-config-js-L2-L3
Hey @Carduelis , managed to find a regex that works with hooks and stuff? Thanks!