Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
🚀 SEO, Performance & Deploy  ·  Lesson 29

Performance & Core Web Vitals

Core Web Vitals in simple words

MetricQuestion it answersGoodMain Next.js fix
LCP – Largest Contentful PaintHow fast does the main content appear?< 2.5 sStatic pages, priority hero image
INP – Interaction to Next PaintHow fast does the page react to a tap?< 200 msLess client JS, small Client Components
CLS – Cumulative Layout ShiftDoes content jump while loading?< 0.1width/height on images, next/font
RequestTTFBserver answersFCPfirst textLCPhero visibleInteractiveINP
Timeline of a page load

How to measure

  1. 1npm run build && npm run start (never measure dev mode)
  2. 2Chrome DevTools → Lighthouse → Mobile → Analyze
  3. 3pagespeed.web.dev for the live URL (real-user data after some traffic)
  4. 4Search Console → Core Web Vitals report
Measure, change one thing, measure again

1. Prefer static rendering

A static (○/●) page is served from cache in milliseconds. Avoid cookies()/headers() in layouts; use ISR (revalidate) instead of SSR for content that changes occasionally.

2. Images and fonts

  • <Image> everywhere, correct sizes, priority only on the hero.
  • next/font with display: 'swap'; 1–2 font families, few weights.
  • Compress source images (EduSite course images are 1200×675 PNG; Next.js serves WebP).

3. Send less JavaScript

JSX – keep client islands small
// ❌ whole page becomes client JS
'use client'
export default function CoursePage() { /* big page + one Like button */ }

// ✅ page stays on the server, only the button ships JS
export default function CoursePage() {
  return (<>
    <BigServerContent />
    <LikeButton />          {/* 'use client' inside this small file */}
  </>)
}
Terminal – bundle analyzer
# See which packages make your JavaScript big (Turbopack bundle analyzer)
npx next experimental-analyze

# Then open the printed local URL and look for large modules

4. Lazy-load heavy components

JSX – next/dynamic
// app/courses/[slug]/page.jsx
import dynamic from 'next/dynamic'

// The chart library (≈ 200 KB) loads only when this component is rendered
const FeeChart = dynamic(() => import('@/components/FeeChart'), {
  loading: () => <p>Loading chart…</p>,
})

// In a Client Component you can also skip server rendering:
// const Map = dynamic(() => import('./Map'), { ssr: false })

5. Third-party scripts with next/script

JSX – next/script strategies
// app/layout.jsx
import Script from 'next/script'

<Script src="https://www.googletagmanager.com/gtag/js?id=G-XXXX" strategy="afterInteractive" />
<Script id="ga" strategy="afterInteractive">
  {`window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date()); gtag('config', 'G-XXXX');`}
</Script>

// Chat widget that is not urgent:
<Script src="https://widget.example.com/chat.js" strategy="lazyOnload" />

beforeInteractive

  • Blocks the page
  • Only for critical scripts (consent)
  • Rarely needed

afterInteractive / lazyOnload

  • Loads after the page is usable
  • Analytics, ads, chat
  • Protects LCP and INP
Pick the latest strategy that still works

6. Fast data

  • Promise.all for independent queries; database indexes on columns in WHERE.
  • Cache with revalidate / tags; stream slow parts with <Suspense>.
  • Host the server close to your users (Mumbai region for India).

Before-launch checklist

  1. 1Lighthouse mobile: Performance ≥ 90, SEO 100, Accessibility ≥ 95
  2. 2No console errors; no 404 for images/fonts
  3. 3All images via next/image with alt text
  4. 4Analytics via next/script afterInteractive
  5. 5Build output: content pages ○/● not ƒ
EduSite passes all five
EduSite mobile home page
EduSite on mobile — static page, optimized hero image, self-hosted font

Common mistakes

  • Measuring in dev mode → numbers are meaningless.
  • Huge libraries for small jobs (moment.js for one date) → use Intl.DateTimeFormat.
  • Auto-playing hero videos on mobile → kills LCP; use a poster image.

Summary

  • LCP, INP, CLS are the three numbers Google uses.
  • Static rendering + next/image + next/font solve most problems.
  • Small client islands, next/dynamic, next/script keep JavaScript low.
✅ Practice

Run Lighthouse (mobile) on your production build, write down the three metrics, apply two fixes from this lesson and measure again.

Frequently Asked Questions

Why is my Lighthouse score low in npm run dev?
Development mode is not optimized. Always test with npm run build and npm run start, or on the deployed site.
What is a good LCP?
Under 2.5 seconds on mobile is good. Next.js static pages with an optimized hero image usually reach under 1.5 seconds.
Does Google Analytics slow down Next.js?
It can if loaded early. Load it with next/script strategy="afterInteractive" or lazyOnload so it does not block the page.
← Next.js Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

Next topicDeploy Next.js (Vercel, VPS, Static) Your progress: 29 / 37 (78%) · Lesson 30 / 37 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free