DEV Community

Cover image for 🚀How to Optimize Performance in your Next.js App🧙✨
Arindam Majumder
Arindam Majumder Subscriber

Posted on

🚀How to Optimize Performance in your Next.js App🧙✨

Introduction

"First impression is the last impression" - It's also true for User experience. If your application does not perform well at first glance, it can create a negative experience.

Recently, I was working on one of side projects and after some time, I noticed -

"Why is the app moving so slowly?"

GIF

Then I thought of optimizing my Next.js application to improve it's overall experience. I explored and implemented various techniques to achieve this.

In this Article, I'll share how to optimize the performance of our next.js application and some tips regarding that!

So, Without delaying any further, let's START!


Built-in Optimizations

Next.js provides us some built-in compoenets that helps to optimize the overall performance of our application.

Image Optimization

Responsive image filling the width and height of its parent container

One of the most common reasons of performance issues is unoptimized images. It does play a big role in typical website’s page weight and can have a sizable impact on your website's LCP performance.

To solve this problem, Next.js provides us the <Image /> component that optimizes the images by default. It extends the HTML <img> element with some optimization features:

  1. Size Optimization: Next.js automatically determines the height and width for local images and makes sure that images are served in the appropriate sizes. This reduces both bandwitch usage and load time.

  2. Visual Stability: Using width and height attributes Next.js determines the correct aspect ratio of image and avoid layout shift from the image loading in. This is why height and width of an image is required by default.

  3. Faster page loading: Next.js uses native browser lazy loading and loads the images only when it's required that is when it comes in the veiwport. It also uses others techniques like caching, preloading to reduce the load time.

An example of the use of the <Image /> component:

import Image from 'next/image'
import profilePic from './me.png'

export default function Page() {
  return (
    <Image
      src={profilePic}
      alt="Picture of the author"
      // width={500} automatically provided
      // height={500} automatically provided
      // blurDataURL="data:..." automatically provided
      // placeholder="blur" // Optional blur-up while loading
    />
  )
}
Enter fullscreen mode Exit fullscreen mode

The next/image component and Next.js Image Optimization API can be configured in the next.config.js file. If you want to know more about next/image, check this:


Link Optimization

Another out-of-the-box optimization feature that Next.js provides is the <Link /> component. Unlike the traditional <a></a> tags next/link component prefetches a page in the background and improves the overall navigation performance.

When a <Link /> component enters the user's viewport, Next.js prefetches and loads the linked route (denoted by the href) and its data in the background to improve the performance of client-side navigations.

Note: Prefetching is only enabled in production.

Additionally, we can pass props to the next/link to give us better control over the navigation behavior.

An example use of Link Component:

import Link from 'next/link'

export default function Page() {
  return (
    <Link href="/dashboard" prefetch={false}>
      Dashboard
    </Link>
  )
}
Enter fullscreen mode Exit fullscreen mode

Font Optimization

Next.js provides next/font component that optimizes font. This component prevents external network requests for fonts and improves performance and enforces privacy.

next/font also provides built-in automatic self-hosting for any font file. With this, we can optimally load web fonts with zero layout shifts. It can smoothly incorporate any Google font into our application and no requests are sent to Google by the browser.

An Example of the Font Component:

import { Inter } from 'next/font/google'

// If loading a variable font, you don't need to specify the font weight
const inter = Inter({
  subsets: ['latin'],
  display: 'swap',
})

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en" className={inter.className}>
      <body>{children}</body>
    </html>
  )
}
Enter fullscreen mode Exit fullscreen mode

🎥 Watch: Learn more about using next/font:


Script Optimization

Third party scripts like analytics and social media widgets significantly impacts the performance and user experiecne of our Application.

To solve that, Next.js provides next/script component that optimally loads third party scripts and optimizes the loading time of the application. Next.js makes sure that the script will only load once, even if a user navigates between multiple pages.

Here's an example Code:

import Script from 'next/script'

export default function MyApp({ Component, pageProps }) {
  return (
    <>
      <Component {...pageProps} />
      <Script src="https://example.com/script.js" />
    </>
  )
}
Enter fullscreen mode Exit fullscreen mode

By default, next/script allows us to load third-party scripts in any page or layout. However, we can fine-tune its loading behavior by using the strategy property:


Dynamic Imports

We often load the Client Components and imported libraries in the initial app/page load which significantly increases the Page Load time and impacts user experience.

Next.js Supports dynamic imports, so instead of importing everything in the initial load, we can dynamically import them only when they are required. It reduces the initial bundle size and improves the load time of our application.

Here's an example of this:

import dynamic from 'next/dynamic'

// Dynamic Component:
const DynamicComponent = dynamic(() => import('../components/DynamicComponent'))

export default function DynamicComponentExample() {
  return (
    <div>
      <DynamicComponent />
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Bundle Analyzer

By bundling external packages we can significantly improve the performance of our application. By Default, Next.js automatically bundles packages imported inside Server Components.

Next.js also provides a plugin @next/bundle-analyzer to manage the size of our application bundles. It generates a visual report of the size of each package and its dependencies.

Based on that report, we can identify the packages that are taking large spaces to then split them and lazy load some parts them to Optimize performance.


Remove unused packages

We often forget to remove unused packages defined in the package.json which creates unnecessary load for our application and impacts its performance.

We can easily identify such unused packages using tools like depcheck . It gives us the list of unused packages which makes it easier for us to identify and remove them.

With that, We can reduce load from our application and get optimal performance.

A terminal window showing the results of running the command  raw `npx depcheck` endraw . The output lists unused dependencies, unused dependencies, and missing dependencies for a project.


Remove unused CSS and JS

Just like packages, unused JavaScript and CSS also affect our application's performance. There are various tools to remove them to reduce bundle size and optimize performance.

Tools like PurgeCSS help us to remove unused CSS from our application. Similarly, tools like Terser also help us to minify your JavaScript files, reducing their size and improving your application’s LCP.


Conclusion

In this article, I've tried to cover some ways to optimize the performance of your Next.js Application.

However, there are many other ways to improve your app performance out there, If you know some more ways, feel free to write them in the comments.

If you found this blog post helpful, please consider sharing it with others who might benefit from it. You can also follow me For More Content like this:

For Paid collaboration mail me at : arindammajumder2020@gmail.com

Connect with me on Twitter, LinkedIn, Youtube and GitHub.

Thank you for Reading : )

Top comments (0)