Next.js is now considered the framework for building the modern Internet. Its built-in features, server-side rendering capabilities, and seamless integration with React have made it a top 3 solution among developers. At the same time, tuning a Next.js production application requires some work to achieve high-level performance, short loading times, and an excellent user experience.
In this guide, you will dig into the essential strategies and best practices to deploy Next.js to production!
7 Best Practices to Follow Before Deploying Next.js to Production
Let’s explore the most important best practice to optimize Next.js for production.
1. Take Advantage of Next.js’ Built-In Optimization Features
Next.js comes with built-in optimization features to take the performance of your production application to the next level. All you have to do to leverage them is to integrate them into your project, as explained in the documentation. These include:
- Image Optimization:
<Image>component that extends the traditional HTML
<img>element with automatic image optimization capabilities. In detail, it allows Next.js to:
- Serve images in the best size depending on the user’s device.
- Automatically convert them to modern image formats like WebP and AVIF.
- Prevent layout shift errors when loading images in the frontend.
- Load them only when they enter the viewport, using native browser lazy loading.
- Resize images on-demand, even for remote files.
- Font Optimization:
next/fontoptimizes local fonts and removes external network requests for improved privacy and performance. As of Next.js 13, it supports self-hosting on any Google Font to avoid making requests to retrieve font files from Google.
- Script Optimization:
<Script>component that extends the traditional HTML
2. Configure Caching and Use Incremental Static Regeneration Whenever Possible
Next.js treats file inside the
/public folder as static assets. For example, if you store a
logo.png image file in
/public, you can then reference it in your code as
<Image src="/logo.png" alt="Company's Logo" width="200" height="200" />Code language: HTML, XML (xml)
Here is why, by default, Next.js add the following header in production for those assets:
Cache-Control: public, max-age=31536000, immutableCode language: PHP (php)
This instructs the browser to cache those files for one year. So, if your Next.js site relies on some static resources, you should download and place them inside
Similarly, Next.js can cache statically generated pages through Incremental Static Regeneration (ISR). Thanks to this feature, new static pages can be created or updated after the application has been built.
To enable ISR, set the
revalidate option in
This is how ISR works:
- The site initially shows the pre-rendered page generated at build time.
- Within 10 seconds, it will continue to display the initial page.
- When a request arrives after 10 seconds from the last regeneration, the framework triggers a background regeneration of the page.
Note that a Next.js production app only regenerates static pages that are requested by users to save resources.
3. Integrate an Analytics or APM Tool
Once a Next.js site is in production, you need a way to track its performance. In particular, you should have a system in place to monitor page views and get information about site traffic.
When deploying to Vercel, you can achieve that with Next.js Speed Insights. This tool allows you to analyze and measure the performance of your application’s pages using various metrics. To enable it:
- Turn on the Web Analytics option in the Vercel Dashboard.
- Add the
@vercel/analyticspackage to your project’s dependencies with
npm i @vercel/analytics
- Use the
<Analytics />component to inject the analytics script into your app.
- Deploy your app to Vercel, and data should start flowing to the Analytics view.
Similarly, you need a service that tracks site performance, alerts you when something goes wrong or the site goes offline, and collects information about bugs and runtime errors. This is what Application Monitoring (APM) is all about.
4. Set Up a Logging System
console object. The most popular ones are:
console.clear(): Clears the browser console.
console.log(): Logs general information.
console.debug(): Logs a debug message in the browser console and a regular message on the server.
console.error(): Logs an error message.
console.warn(): Logs a warning message in the browser console or an error message on the server
console.time(): Starts a timer that can be used to compute the duration of an operation.
console.timeEnd(): Stops the timer and prints the duration of the operation.
If you instead prefer a more structured solution, Next.js recommends
5. Enable Error Handling With Custom 500 and 400 Pages
Like any other application, Next.js sites are subject to errors. One of the most important aspects of error handling is presenting meaningful error messages to users to inform them of what happened. When an error occurs in the frontend or backend, Next.js displays this static 500 page:
As you can see, this page is not informative at all and may result in a bad user experience for visitors. This is why Next.js supports custom 500 pages.
If you are a Pages Router user, create a
500.js page under
This represents the frontend page components that will be shown to users in case of errors.
If you are an App Router user, create an
error.js file under
Note that this must be a client component.
Next.js also supports a static 404 page, which is rendered:
- When the object returned by
notFound: truein a Pages Router app.
- When the
notFound()function is called in an App Router app.
Again, the default 404 page is not the best:
To customize it, if you are a Pages Router user, create a
404.js page under
If you are an App Router user, define a
not-found.js file under
6. Reduce the Size of the Build Bundle
Producing a minimized bundle is great, as clients will take less time and network bandwidth to download and render the Next.js production app.
The goal is to try to reduce those bundles to the bare while preserving functionality. For this purpose, you can use dynamic imports via
To analyze the bundle produced by Next.js and get guidance on how to reduce its size, you can use the following tools:
- Webpack Bundle Analyzer: To visually explore the size of webpack output files in an interactive treemap.
- Package Phobia: To analyze the cost of adding a new dependency to your project.
- Bundle Phobia: To analyze how much a dependency will increase the bundle size.
- bundlejs: To quickly bundle and minify your project in your browser.
- Import Cost: To display the size of any imported package inside Visual Studio Code.
7. Optimize Page SEO Performance With Lighthouse
The ultimate goal of most Next.js sites is to produce excellent SEO results. Google has changed its approach to SEO performance evaluation a great deal over time, and it now focuses primarily on Core Web Vitals:
- Largest Contentful Paint (LCP): Measures the time it takes for the main content of a page to become visible to users.
- First Input Delay (FID): Evaluates the time delay between a user’s first interaction and the browser’s response.
- Cumulative Layout Shift (CLS): Gauges the visual stability of a page by measuring the number of unexpected layout shifts that may annoy users.
Recommended article: React Libraries for Boosting UI Design
These represent user experience metrics that Google uses to assess and quantify the overall performance of web pages and define their ranking in search results.
The best tool for optimizing these indicators is Google Lighthouse, an open-source tool built into Chrome that can be run on any web page to check its SEO performance.
To optimize Next.js for production, you should build the project, start it, open it in Incognito mode in the browser, and launch Lighthouse on each page. This will provide guidance and best practices for improving site performance, accessibility, and SEO.
In this article, you looked at what to do to make a Next.js application production-ready. As you learned here, this involves enabling caching, using the advanced built-in optimization features, and setting up a performance logging and monitoring system.
Through several examples and insights, you had the opportunity to see how to build a reliable Next.js production site. Deploying a top-notch site has never been easier!
Thanks for reading! We hope you found this article helpful!