DEV Community

swhabitation
swhabitation

Posted on • Originally published at swhabitation.com

How to Optimize or Improve Google Page Speed in Next.js?

A slow website is so frustrating for end-users and too bad for SEO. If your Next.js site takes too much time to load, visitors might leave your website before they even see your content. Google also ranks faster websites higher, so speed is the most important thing.

Next.js is built for performance, and with a few simple customization, you can make your site load faster and score well on Google PageSpeed Insights.

In this blog, we are going to learn,

  • Why speed matters for SEO and user experience ?
  • Common reasons why Next.js sites are slow.
  • Easy ways to optimize your site for faster loading times.

Why Page Speed Matters ?

A slow website can cause,

  • High bounce rates: End users leave your website if a page of it takes too much time to load. Lets see what the Bounce Rate is ? Its a metric that measures the percentages of website visitors who leave the website after viewing only one page. It shows how your website is connected with users.
  • Lower SEO rankings: Google prefers fast loading websites.
  • Poor user experience: Nobody likes waiting for a page to load.

Google measures website performance using Core Web Vitals, which include:

Largest Contentful Paint (LCP)

LCP : How long it takes to load the biggest element on your page.
Image description

The largest element is generally a featuer image or any h1 tag, including below as well,

  • Image element
  • Image element inside svg
  • Video element
  • Any element with background image that loaded vis url() function
  • Block level elements that containing textor other inline level elements text.
  • The first frame of an animated image format, like any animated GIF
  • Image inside video element

Anything that the outside of the viewport or any overflow as well is not considering while measuring the LCP. For example, If any image occupies the entire viewport its not considered for LCP.

A good LCP value is less than 2.5 seconds [< 2.5 seconds].It sholuld be based on chrome user experience report (CrUX) data.

  • Good: <=2.5s
  • Needs improvement: >2.5s and <=4s
  • Poor: >4s

First Input Delay (FID)

FID : How quickly your page responds to user actions.
Image description

The user interactions in terms of,

  • Click on any link or button
  • Input any text into blank field
  • Clicking checkbox
  • Selecting any dropdown menu
  • Events like scrolling or zooming are excluded

A good FID value is less than 100 ms. It should be based on Chrome User Experience Report (CrUX) data.

now what is CrUX data ? Its a data from the actual users of chrome who are on your site. You need 75% of interactions to respond in less than 100ms.

  • Good: <=100 ms
  • Needs improvement: >100 ms and <=300 ms
  • Poor: >300 ms

Cumulative Layout Shift (CLS)

CLS : How stable your page layout is while loading.
Image description

CLS is calculated during the 5 second duration while the most shifing occurs. The main reason behind this occurs is when you try to click somthing ona page that shifts and then ending up by clicking on somthing you dont want to.

Common scenarios are below,

  • Images without dimensions [ widht and height ]
  • Content with javascript
  • Any ads, embeds, and iframes without dimensions
  • Web fonts that causes FOIT [Flash of Invisible Text] or FOUT [Flash of Unstyled Text]
  • Javascript animations
  • Content that appears after the page load

A good CLS value is less than or equal to 0.1. It should be based on Chrome User Experience Report (CrUX) data.

  • Good: <=0.1
  • Needs improvement: >0.1 and <=0.25
  • Poor: >0.25

Now, let’s look at how to improve page speed in Next.js ?

Easy Ways to Optimize Page Speed in Next.js

1. Optimize Images with Next.js Component

In our regular HTML, we have added any image like below snippet,

<img src="image.png" alt="Image" />
Enter fullscreen mode Exit fullscreen mode

We have to manually optimize below things,

  • Image is responisive based on the screen sizes
  • Optimize image with any third party toll or library
  • As the image is about to enter on viewport lazy load them.

Large images may slow down websites. Next.js provides an optimized component that,

  • Lazy loads images (loads them only when needed)
  • Automatically converts them to modern formats like WebP
  • Resizes images for different screen sizes

Use this instead of regular tags:

import Image from "next/image";

<Image 
  src="/example.png" 
  width={400} 
  height={400} 
  alt="Example Image" 
  priority
/>
Enter fullscreen mode Exit fullscreen mode

Use priority={true} for images above the fold (visible when the page first loads).

2. Use Static Site Generation (SSG) for Faster Loading

If your page doesn’t change frequently then pre-render it at the build time using SSG. This makes it load quickly without waiting for a server response.

Example of SSG in Next.js:

export async function getStaticProps() {
  const res = await fetch("https://api.example.com/data");
  const data = await res.json();

  return { props: { data } };
}
Enter fullscreen mode Exit fullscreen mode

✔ It is best for blogs, landing pages and marketing websites.

3. Enable Incremental Static Regeneration (ISR) for Updated Content

If your content changes frequently, but you still want the speed of SSG, use ISR. This updates static pages without rebuilding the entire website.

Lets check this by an xample of ISR,

export async function getStaticProps() {
  const res = await fetch("https://api.example.com/data");
  const data = await res.json();

  return { props: { data }, revalidate: 60 }; // Updates every 60 sec
}
Enter fullscreen mode Exit fullscreen mode

✔ It is perfect for news sites, blogs, and product pages.

4. Load JavaScript Only When Needed

Too much javascript may slow down a website. Next.js allows lazy loading, which means scripts load only when required.

Lazy load large components:

import dynamic from 'next/dynamic';

const HeavyComponent = dynamic(() => import('../components/HeavyComponent'), { ssr: false });
Enter fullscreen mode Exit fullscreen mode

This speeds up initial page load.

Lazy load third-party scripts like Google Analytics:

import Script from "next/script";

<Script 
  src="https://www.googletagmanager.com/gtag/js?id=UA-XXXXXX-X" 
  strategy="lazyOnload" 
/>
Enter fullscreen mode Exit fullscreen mode

✔ It reduces unnecessary network requests.

5. Reduce Unused CSS and JavaScript

For Tailwind users, use PurgeCSS to remove unused styles.

module.exports = {
  purge: ['./pages/**/*.js', './components/**/*.js'],
};
Enter fullscreen mode Exit fullscreen mode

Analyze your JavaScript bundle with Webpack Bundle Analyzer:

npm install --save-dev @next/bundle-analyzer
Enter fullscreen mode Exit fullscreen mode

Add below code-snippet to next.config.js,

const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
});

module.exports = withBundleAnalyzer({});
Enter fullscreen mode Exit fullscreen mode

Then run,

ANALYZE=true next build
Enter fullscreen mode Exit fullscreen mode

6. Use a CDN (Content Delivery Network) for Faster Loading

A CDN stores your website files on multiple servers worldwide, so users can load them from the nearest location.

Deploy on Vercel (best CDN for Next.js):

vercel deploy
Enter fullscreen mode Exit fullscreen mode

✔ Global content distribution
✔ Automatic performance optimizations

7. Optimize Fonts for Faster Rendering

Fonts can slow down page load times, so use Next.js Google Fonts Optimization instead of manually importing fonts.

next/font will automatically optimize your fonts including custom fonts and remove external network requests for improved privacy and performance.

Lets get started by importaing the font you would like to use from next/font/google as a function. Nextjs recommended using variable fonts for the best performance and flexibility.

To use the fonts in all your pages, add it to _app.js file under /pages,

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'] })

export default function MyApp({ Component, pageProps }) {
  return (
    <main className={inter.className}>
      <Component {...pageProps} />
    </main>
  )
}
Enter fullscreen mode Exit fullscreen mode

If you cant use a variable font, you will need to specify a weight,

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

const roboto = Roboto({
  weight: '400',
  subsets: ['latin'],
})

export default function MyApp({ Component, pageProps }) {
  return (
    <main className={roboto.className}>
      <Component {...pageProps} />
    </main>
  )
}
Enter fullscreen mode Exit fullscreen mode

You can specify multiple weights and or styles by using an array,

const roboto = Roboto({
  weight: ['400', '700'],
  style: ['normal', 'italic'],
  subsets: ['latin'],
  display: 'swap',
})
Enter fullscreen mode Exit fullscreen mode

Tip : Its a good practise to use (_) for font names with multiple words. Just like Roboto Mono will be importaed as Roboto_Mono.

You can also use the font without a wrapper and classname by adding it inside the

Top comments (0)