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,
A slow website can cause,
Google measures website performance using Core Web Vitals, which include:
LCP : How long it takes to load the biggest element on your page.
The largest element is generally a featuer image or any h1 tag, including below as well,
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.
FID : How quickly your page responds to user actions.
The user interactions in terms of,
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.
CLS : How stable your page layout is while loading.
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,
A good CLS value is less than or equal to 0.1. It should be based on Chrome User Experience Report (CrUX) data.
Now, let’s look at how to improve page speed in Next.js ?
In our regular HTML, we have added any image like below snippet,
1
<img src="image.png" alt="Image" />
We have to manually optimize below things,
Large images may slow down websites. Next.js provides an optimized <Image> component that,
Use this instead of regular <img> tags:
1
2
3
4
5
6
7
8
9
import Image from "next/image";
<Image
src="/example.png"
width={400}
height={400}
alt="Example Image"
priority
/>
Use priority={true} for images above the fold (visible when the page first loads).
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:
1
2
3
4
5
6
export async function getStaticProps() {
const res = await fetch("https://api.example.com/data");
const data = await res.json();
return { props: { data } };
}
✔ It is best for blogs, landing pages and marketing webistes.
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,
1
2
3
4
5
6
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
}
✔ It is perfect for news sites, blogs, and product pages.
Too much javascript may slow down a website. Next.js allows lazy loading, which means scripts load only when required.
Lazy load large components:
1
2
3
import dynamic from 'next/dynamic';
const HeavyComponent = dynamic(() => import('../components/HeavyComponent'), { ssr: false });
This speeds up initial page load.
Lazy load third-party scripts like Google Analytics:
1
2
3
4
5
6
import Script from "next/script";
<Script
src="https://www.googletagmanager.com/gtag/js?id=UA-XXXXXX-X"
strategy="lazyOnload"
/>
✔ It reduces unnecessary network requests.
For Tailwind users, use PurgeCSS to remove unused styles.
1
2
3
module.exports = {
purge: ['./pages/**/*.js', './components/**/*.js'],
};
Analyze your JavaScript bundle with Webpack Bundle Analyzer:
1
npm install --save-dev @next/bundle-analyzer
Add below code-snippet to next.config.js,
1
2
3
4
5
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
});
module.exports = withBundleAnalyzer({});
Then run,
1
ANALYZE=true next build
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):
1
vercel deploy
✔ Global content distribution
✔ Automatic performance optimizations
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,
1
2
3
4
5
6
7
8
9
10
11
12
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>
)
}
If you cant use a variable font, you will need to specify a weight,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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>
)
}
You can specify multiple weights and or styles by using an array,
1
2
3
4
5
6
const roboto = Roboto({
weight: ['400', '700'],
style: ['normal', 'italic'],
subsets: ['latin'],
display: 'swap',
})
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 <head/> just like below at pages/_app.js,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { Inter } from 'next/font/google'
const inter = Inter({ subsets: ['latin'] })
export default function MyApp({ Component, pageProps }) {
return (
<>
<style jsx global>{`
html {
font-family: ${inter.style.fontFamily};
}
`}</style>
<Component {...pageProps} />
</>
)
}
✔ Reduces render-blocking resources
✔ Improves Core Web Vitals
By following above steps, your Next.js website will load faster, rank better on google, and improve user experience.
✅ Optimize images with Next.js <Image> component
✅ Use Static Site Generation (SSG) for fast-loading pages
✅ Implement ISR to update content without full rebuilds
✅ Lazy load JavaScript and third-party scripts
✅ Minify CSS and remove unused JavaScript
✅ Deploy on Vercel for best performance
A fast website keeps users happy, improves SEO, and boosts conversions. Try out these optimizations today and watch your page speed score improve.