vercel / next.js

The React Framework
https://nextjs.org
MIT License
125.51k stars 26.81k forks source link

NextJs compiling extremely slow #29559

Closed stevensturkop closed 1 year ago

stevensturkop commented 3 years ago

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.

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" } }
pimmee commented 1 year ago

@timneutkens Appreciate the response.

You're right, NextJS has tooling to debug compiled modules with trace-to-tree.mjs. I've used it before but still struggling to find obvious root causes of slow compile times. It seems to me that it's the accumulation of dependencies (e.g. axios 2.2s, @casl/ability 2.1s, etc.) that's causing most of it. Perhaps I'm missing something obvious that would make a big difference?

https://gist.github.com/pimmee/9b448450782a63e93a131a9f8c54afb7

Really looking forward to turbo pack adding support for app dir and more 🚀

sneko commented 1 year ago

@timneutkens if you have in mind a Next.js project working smoothly with MUI in development I'm curious to see it!

In addition to what I mentionned (long duration just to launch next dev or browse a new page), when reloading a page in my browser without changing any code it seems to recompile thousands of modules... taking like 10 seconds to do so.

If I have to choose between MUI or Next.js... hard to choose once a project is launched :D ...

About Turbopack I'm not sure it's a solution before years... for little projects it may be fine but since there will be no compatibility with current webpack plugins... the migration will be hard for quite some time before the community catch up on plugins.

sneko commented 1 year ago

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:

    modularizeImports: {
      '@mui/material': {
        transform: '@mui/material/{{member}}',
      },
      '@mui/icons-material/?(((\\w*)?/?)*)': {
        transform: '@mui/icons-material/{{ matches.[1] }}/{{member}}',
      },
    },

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:

import { Grid, Typography } from '@mui/material';

by:

import Grid from '@mui/material/Grid';
import Typography from '@mui/material/Typography';

I also replaced for example:

import { LocalizationProvider } from '@mui/x-date-pickers';
import { frFR as coreFrFR } from '@mui/material/locale';
// import { DataGrid, frFR as dataGridFrFR } from '@mui/x-data-grid';
import { frFR as datePickerFrFR } from '@mui/x-date-pickers';

by:

import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { frFR as coreFrFR } from '@mui/material/locale';
// import { frFR as dataGridFrFR } from '@mui/x-data-grid/locales/frFR';
import { frFR as datePickerFrFR } from '@mui/x-date-pickers/locales/frFR';

import { fr as frDateLocale } from 'date-fns/locale';
import { format as formatDate, formatDistance, formatRelative, isDate } from 'date-fns';

by:

import frDateLocale from 'date-fns/locale/fr';
import formatDate from 'date-fns/format';
import formatDistance from 'date-fns/formatDistance';
import formatRelative from 'date-fns/formatRelative';
import isDate from 'date-fns/isDate';

(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 to pnpm? (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 of pnpm a dependency with the exact same version in 2 packages would not be merged into one (it's deduplicated). It's more specific to pnpm so if you want this, I tried to explain a bit how to debug/fix this: https://github.com/pnpm/pnpm/discussions/6055#discussioncomment-5018827

Now 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!

yanetou commented 1 year ago

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

macutko commented 1 year ago

https://github.com/vercel/next.js/issues/29559#issuecomment-1323379937

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.

7iomka commented 1 year ago

In case it helps somebody, in our case the line causing the extremely slow compilation was this one:

//tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  // eslint-disable-next-line global-require, import/no-extraneous-dependencies
  presets: [require('tailwind-preset')],
  content: [
    './src/app/**/*.{js,ts,jsx,tsx}',
    './src/pages/**/*.{js,ts,jsx,tsx}',
    './src/components/**/*.{js,ts,jsx,tsx}',
    './src/layout/**/*.{js,ts,jsx,tsx}',
    '../../packages/ui/**/*.{js,ts,jsx,tsx}', // 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

fixed it for me, thanks!

Hi. but, how you found workaround to not include paths from one of packages if you really need this?

DylanP97 commented 1 year ago

Hello,

For me after making a next analyze It was the use of "react-icons", "date-fns" and "world-countries" that were calling taking ridiculously too much kilobytes

also dynamic and splited import help to enhance the speed

but run a next analyze you will see what's taking a lot of space

turkialanizi78 commented 1 year ago

for me i get more speed after i unselect the Format On Save

billymcintosh commented 1 year ago

Thats is nothing to do with nextjs mate.

Change your IDE and test.

On Fri, 26 May 2023 at 23:16, bofaissal alanizi @.***> wrote:

for me i get more speed after i unselect the Format On Save

— Reply to this email directly, view it on GitHub https://github.com/vercel/next.js/issues/29559#issuecomment-1564625193, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABVFM6N2QDF6JHDCOXGCNDXIDJOHANCNFSM5FGHOMJA . You are receiving this because you were mentioned.Message ID: <vercel/next .@.***>

lveillard commented 1 year ago

In case it helps somebody, in our case the line causing the extremely slow compilation was this one:

//tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  // eslint-disable-next-line global-require, import/no-extraneous-dependencies
  presets: [require('tailwind-preset')],
  content: [
    './src/app/**/*.{js,ts,jsx,tsx}',
    './src/pages/**/*.{js,ts,jsx,tsx}',
    './src/components/**/*.{js,ts,jsx,tsx}',
    './src/layout/**/*.{js,ts,jsx,tsx}',
    '../../packages/ui/**/*.{js,ts,jsx,tsx}', // 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

fixed it for me, thanks!

Hi. but, how you found workaround to not include paths from one of packages if you really need this?

So in our case we were forced to split tailwind instead of having it in a single branch of the monorepo

sannajammeh commented 1 year ago

In case it helps somebody, in our case the line causing the extremely slow compilation was this one:

//tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  // eslint-disable-next-line global-require, import/no-extraneous-dependencies
  presets: [require('tailwind-preset')],
  content: [
    './src/app/**/*.{js,ts,jsx,tsx}',
    './src/pages/**/*.{js,ts,jsx,tsx}',
    './src/components/**/*.{js,ts,jsx,tsx}',
    './src/layout/**/*.{js,ts,jsx,tsx}',
    '../../packages/ui/**/*.{js,ts,jsx,tsx}', // 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

Just going to mention that ui most likely had a node_modules in it. I switched from /ui/**/*.tsx to /ui/src/**/*.tsx and it become quite a bit faster.

kcritesh commented 1 year ago

"dev": "next dev --turbo", using turbopack worked for me https://nextjs.org/docs/architecture/turbopack

Vallo commented 1 year ago

@kcritesh turbopack is in beta, not production ready, and produces a lot of errors in some projects.

timneutkens commented 1 year ago

I'm going to consolidate all of these issues into one issue given that they're all roughly the same.

Closing in favor of #48748. Please see this comment: https://github.com/vercel/next.js/issues/48748#issuecomment-1578374105

timneutkens commented 5 months ago

In case you're using a monorepo with Tailwind CSS, have a look at this: https://twitter.com/timneutkens/status/1783851267237781574