• 24-Jan-2023
Lightrun Team
Author Lightrun Team
Share
This article is about fixing NextJs compiling extremely slow in Vercel Next.js

NextJs compiling extremely slow in Vercel Next.js

Lightrun Team
Lightrun Team
24-Jan-2023

Explanation of the problem

I am currently using version 11.1.2 of Next.js and version 14.18.0 of Node.js. The browser I am using is Chrome and my operating system is Windows 10. I am deploying my application on AWS ECS.

I am experiencing an issue with slow development performance in my Next.js application. After running “npm run dev” and navigating to localhost:3000, the initial page load takes up to 60 seconds. Additionally, code changes made using fast refresh or page transition SSR result in compilation times between 15-20 seconds, and in some cases, can take over 30 seconds or fail to compile altogether.

I have attempted to resolve the issue by disabling Windows Defender, as suggested in the GitHub issue linked here: https://github.com/vercel/next.js/issues/12797#issuecomment-660225689. However, this did not resolve the issue. I am also not using webpack 5 and Tailwind CSS in my project, so they are not a contributing factor to the slow performance. I am not able to provide a reproducible UI as the project I am working on is under NDA. I would appreciate any suggestions on how to improve or fix the compilation time on Windows.

Troubleshooting with the Lightrun Developer Observability Platform

Getting a sense of what’s actually happening inside a live application is a frustrating experience, one that relies mostly on querying and observing whatever logs were written during development.
Lightrun is a Developer Observability Platform, allowing developers to add telemetry to live applications in real-time, on-demand, and right from the IDE.

  • Instantly add logs to, set metrics in, and take snapshots of live applications
  • Insights delivered straight to your IDE or CLI
  • Works where you do: dev, QA, staging, CI/CD, and production

Start for free today

Problem solution for NextJs compiling extremely slow in Vercel Next.js

On-demand-entries is a feature in Next.js that compiles the JS/CSS/etc for pages on-demand when they are requested. This is done in order to ensure that a Next.js application with a large number of pages does not slow down. However, this can result in slow compilation times when the pages are requested. This can be caused by the large number of modules that Next.js has to process, as the user in the first answer has experienced.

The proposed solution to this issue is integrating SWC (Super-Fast Compiler) with full backwards compatibility. SWC is a super-fast compiler that can significantly speed up the compilation process. It works by converting JavaScript code into a more efficient form that is faster to process. By integrating SWC with full backwards compatibility, the user will be able to improve the performance of on-demand-entries without breaking any existing functionality. This can be achieved by adding a flag to the Next.js config file, as seen in the following code block:

module.exports = {
  webpack(config) {
    config.module.rules.push({
      test: /\.js$/,
      use: {
        loader: '@swc/loader',
        options: {
          jsc: {
            parser: {
              syntax: 'ecmascript',
              jsx: true
            },
            transform: {
              react: true
            }
          }
        }
      }
    });
    return config;
  }
}

It is worth noting that this solution is not a catch-all and each case should be evaluated individually. The user also suggests providing trace file and other files, such as package.json, to help investigate the issue.

In summary, the issue at hand is slow development performance in a Next.js application caused by on-demand-entries. The proposed solution is integrating SWC with full backwards compatibility to improve the performance of on-demand-entries. The user suggests providing trace file and other files to help investigate the issue. It is important to note that the solution may not be a catch-all and each case should be evaluated individually.

Other popular problems with Next.js

Problem: Slow development performance caused by a large number of modules that Next.js has to process

One of the most common problems with Vercel Next.js is slow development performance caused by a large number of modules that Next.js has to process. This can result in long compilation times for pages and slow hot module replacement during development.

Solution:

To resolve this issue, developers can use the modularizeImports configuration in their Next.js config file to reduce the number of modules that Next.js has to process. This can be done by specifying which modules should be transformed and how they should be transformed. Here is an example of how to use the modularizeImports configuration to transform the @mui/material module:

module.exports = {
  experimental: {
    modern: true,
    modularize: true,
    css: true
  },
  webpack(config) {
    config.module.rules.push({
      test: /\.js$/,
      use: [
        {
          loader: 'babel-loader',
          options: {
            presets: [['next/babel', {'preset-env': {modules: 'commonjs'}}]],
            plugins: ['babel-plugin-module-resolver']
          }
        }
      ]
    });
    return config;
  }
}

Problem: Slow performance caused by on-demand-entries

Another common problem with Vercel Next.js is slow performance caused by on-demand-entries. On-demand-entries is a feature in Next.js that compiles the JS/CSS/etc for pages on-demand when they are requested. This is done to ensure that a Next.js application with a large number of pages does not slow down. However, this can result in slow compilation times when the pages are requested.

Solution:

One solution to this problem is to integrate SWC (Super-Fast Compiler) with full backwards compatibility. This can be done by adding the following flag to your Next.js config file:

module.exports = {
    webpack(config) {
        config.module.rules.push({
            test: /\.js$/,
            use: {
                loader: '@swc/loader',
                options: {
                    jsc: {
                        parser: {
                            syntax: 'ecmascript',
                            jsx: true
                        },
                        transform: {
                            react: true
                        }
                    }
                }
            }
        });
        return config;
    }
}

This will convert the JavaScript code into a more efficient form that is faster to process, significantly speeding up the compilation process. It’s worth noting that this solution may not be a catch-all and each case should be evaluated individually.

Problem: Slow performance caused by dynamic imports

Another common problem with Vercel Next.js is slow performance caused by dynamic imports. Dynamic imports allow developers to load chunks of code on demand instead of loading everything at once. This can improve the initial load time of the application, but it can also cause slow performance if not implemented properly.

Solution:

To resolve this issue, developers can use the dynamic imports configuration in their Next.js config file to specify which dynamic imports should be processed and how they should be processed. Here is an example of how to use the dynamic imports configuration to process dynamic imports for the @mui/material module:

module.exports = {
    experimental: {
        modern: true,
        dynamicImports: true,
        css: true
    }
}

This will ensure that the dynamic imports for the @mui/material module are processed correctly and improve the performance of the application.

A brief introduction to Next.js

Next.js is a JavaScript framework for building server-rendered React applications. It is built on top of React and provides a set of features that make it easy to build scalable, high-performance applications. One of its key features is server-side rendering (SSR), which allows for faster initial load times and improved search engine optimization (SEO). With SSR, Next.js renders the initial HTML on the server and sends it to the client, allowing the client to start interacting with the application immediately. This is different from traditional client-side rendering (CSR), where the client must download and execute all of the JavaScript before it can start interacting with the application.

Next.js also provides a set of features that make it easy to build scalable and maintainable applications. For example, it includes a powerful development environment with hot module replacement (HMR) and automatic code splitting. HMR allows developers to see changes in the application without needing to refresh the page, while automatic code splitting ensures that the application only loads the code that is needed for the current page. In addition, Next.js includes built-in support for static exporting, which allows developers to easily create static versions of their applications for faster performance and better scalability. This feature is particularly useful for building statically generated blogs, documentation sites, and landing pages.

Most popular use cases for Next.js

  1. Server-side rendering: Next.js can be used to build server-rendered React applications, which allows for faster initial load times and improved search engine optimization (SEO). With server-side rendering, Next.js renders the initial HTML on the server and sends it to the client, allowing the client to start interacting with the application immediately. This can be achieved by using the getInitialProps method on a page component and passing the data to the render method.
function HomePage({ data }) {
  return (
    <div>
      {data.map(item => (
        <div key={item.id}>{item.title}</div>
      ))}
    </div>
  );
}

HomePage.getInitialProps = async () => {
  const res = await fetch('https://api.com/data');
  const data = await res.json();

  return { data };
};

export default HomePage;
  1. Static site generation: Next.js can also be used to generate static sites, which can be useful for creating blogs, documentation sites, and landing pages. This can be achieved by using the next export command, which will generate a set of static HTML and asset files that can be deployed to a static hosting platform such as GitHub pages or Amazon S3.
  2. API routes: Next.js allows developers to easily add API routes to their applications. This can be done by creating a pages/api directory and adding JavaScript files that export a request handler function. These functions will be executed on the server and can be used to handle data fetching, authentication, or any other server-side logic.
export default (req, res) => {
  res.statusCode = 200;
  res.json({ message: 'Hello World' });
}

This makes it easy to build full-stack applications with Next.js as the front-end and back-end can be developed in the same codebase.

Share

It’s Really not that Complicated.

You can actually understand what’s going on inside your live applications. It’s a registration form away.

Get Lightrun

Lets Talk!

Looking for more information about Lightrun and debugging?
We’d love to hear from you!
Drop us a line and we’ll get back to you shortly.

By submitting this form, I agree to Lightrun’s Privacy Policy and Terms of Use.