Open In App

Next.js Bundle Optimization to improve Performance

Last Updated : 05 Jan, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, We will learn various ways to improve the performance of the NextJS bundle which results in increasing the performance of NextJS applications in Google PageSpeed Insights or Lighthouse.

As per the documentation, NextJS is a React framework that gives you the building blocks to create web applications. 

Building Blocks means various necessary things required to create web applications such as Routing, User Interface, Data fetching, rendering, and much more. 

In NextJS, when we run the command npm run build, NextJS generates an optimized version of your application for production. The output is generated inside the ‘.next’ folder. All bundles inside the ‘.next’ folder are being compiled, minified, and ready to be served on the browser in order to achieve the best performance across all browsers. 

Sometimes, we don’t follow the best practices due to which our performance gets impacted. Below are the ways to achieve better performance in your application:-

1. Dynamic Imports:

Next.JS supports lazy loading through dynamic imports. Components that are not visible during the initial load of an application should not load normally. They should be loaded using dynamic imports which enables lazy loading and hence that component will be sent to the browser when it is needed. 

import dynamic from 'next/dynamic';

//Normal Import
import Starworld from './components/Starworld';

//Dynamic Import
const Startworld= dynamic(()=>import('./components/Starworld'))

2. Choose the right Image Format:

Using the right format Image will be beneficial to reduce the bundle size of a Next.JS application. If you can try to eliminate the image during the initial load will be the best optimization strategy but sometimes, Images at the right position do communicate more than compared to thousand words. 

Images are two types:

  • Vector Based Images(SVGs) used lines, points, and polygons to represent the Images. 
  • Raster Based Images (JPEG, PNG, Webp) represents an image by encoding the individual values of each pixel within a rectangular grid. 

Images are part of  LCP(Large contentful Paint) which means the size of an image impacts the load time of an application. Vector Based Images are ideally suited for geometric shapes like logos, icons, etc as they deliver sharp results for higher resolution screens. Raster Images usually get preferred where there are complex color blends or digital photos. 

In Raster Based Images, Prefer Webp format Images as compared to JPEG or PNG. Usually, webP images are (25%-75%) smaller than JPEG or PNG images. Hence, Improving the performance and reduction in bundle size.

  • Youtube improved the first load performance by 10% through the use of WebP Images.
  • Facebook observed the reduction in JPEG and PNG file size when they switched to WebP format.

3. Optimize Large Contentful Paints:

Large Contentful Paint(LCP) is one of three core web vital metrics. It is a measure of how much time your page takes to display the largest content on the Screen.  LCP should be less than 2.5 seconds to have a good user experience. It is one of the complex tasks to optimize LCP contents as it depends on various factors which results in poor LCP time.  There are various points below that impact the LCP and can be optimized by the below means:-

  • Never Lazy load LCP Image as it will impact the performance of an initial Load. 
  • Preload the LCP content so that it can be loaded as early as possible.
<head>
   <title>Page Title</title>
   <link rel="preload" 
            fetchpriority="high" 
            as="image" 
            href="/path/to/Firstimage.webp" 
            type="image/webp">
</head>
  • Defer your stylesheet into various styles and only load critical styles which are necessary for the initial load.
  • Use CDN(content network delivery) to reduce the load time of a resource by putting the server geographically close to the user. 
  • If your LCP is a font, Try reducing the Font size which will boost the performance of an application.

4. Lazy Load Images for the Web:

The images which are used in the later part of the Application should be lazy loaded. 

  • For Next.JS, Use the built-in Image component(next/image) which optimizes the image and hence boots the performance.
  • Browser-level lazy loading provides also provides a way to lazy load the offscreen images. You can use the ‘loading’ attribute in the <img> tag to defer the loading of offscreen images.
<img src="image.png" loading="lazy" alt="…" width="200" height="200">

5. Use Intersection Observer API:

We can use Intersection Observer API to load the offscreen components on the Home Page. It majorly boosts the performance of an application. Through Intersection observer, you can observe the component, if it is in the viewport, we can load it asynchronously otherwise we don’t need to load the component when it is not needed. 

import { useState, useRef } from "react";
export default function Home(){
    const [toggler, setToggler]= useState(false);
    const [viewPortValue, setViewPortValue]= useState("");
    const ref=useRef();
    const InterSectionObserverComponent= (ref)=>{
        let isViewPort= false;
        const observer= new IntersectionObserver(([entry])=>{
            isViewPort= entry.isIntersecting;
            setViewPortValue(isViewPort);
        });
        if(ref.current){
            observer.observe(ref.current);
        }
    }

}

The above function is used to observe the component.                           

{
    <div ref={ref}>
        {viewPortValue && <Startworld />}
    </div>
}

The above code will load the Starworld Component when ViewPortValue becomes true i.e. component is visible inside the viewport.

6. Specific Imports:

When we just want to import a specific function in a library, Instead of importing the whole library, we can import a specific function. Thus, Reducing the bundle size which impacts the performance of an application. 

//old way
import _remove from 'lodash';
//new way
import _remove from 'lodash/remove';

7. Use Prefetch attribute as false in next/link Component:

When we use the ‘next/link’ component in our Next.JS application. By default, it prefetches the pages whose links are in the viewport. For example, we have a link ‘/career’ and ‘/testimonial’ pages in the Header of a Home Page. Even, User is on the homepage, it will prefetch these career and testimonial components during build time. 

Keep, Prefetch={false} in order to avoid prefetching the page which results in a reduction in bundle size. By adding this attribute, it will prefetch the component by hovering over the link instead of prefetching the pages at load time. 

<Link href="/career" prefetch={false}>
    <a>Career</a>
</Link>

8. Use Bundle Analyzer to analyze the Build:

 Install @next/bundle-analyzer library to analyze the build of the application. Through the Bundle analyzer, we will understand the library sizes used in our application. 

Through the analyzer, we can do the following activities:

  1. We can replace the larger libraries with their smaller alternatives. 
  2. We can remove unnecessary library which is being used in the application.
  3. We can move the bigger library tasks to the server side and through API, we can access the functionality. 

By implementing the above points, we can optimize our NextJS application and hence increase the performance of the Next.JS application. 


Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads