Get in Touch

kowshikvalipireddy@gmail.com
Back to all articles
Web Performance
8 min read

How I Optimized a Next.js Website From a 5.2s LCP to 1.1s (A Real Case Study)

Kowshik Valipireddy

Kowshik Valipireddy

Full Stack Developer & AI Engineer

How I Optimized a Next.js Website From a 5.2s LCP to 1.1s (A Real Case Study)

When we first audited our initial production build on mobile 4G network throttling, the metrics were painful: Largest Contentful Paint (LCP) was clocking in at 5.2 seconds, Time to First Byte (TTFB) was sluggish, and the Lighthouse performance score was hovering around 48/100.

1. The Starting Point: A Sluggish 5.2s LCP

Google considers any LCP over 2.5 seconds to be "Poor" or "Needs Improvement". A slow LCP directly suppresses SEO rankings and increases bounce rates by up to 60%. Here is what the initial audit revealed:

  • Unoptimized hero images: A 2.4MB PNG hero background was loading via standard CSS background-image without responsive resizing or priority preloading.
  • Heavy third-party and client bundles: Animation libraries and charting modules were imported statically in top-level layout components, bloating the initial JS bundle to over 680KB.
  • Render-blocking external fonts: Unhosted web fonts were blocking text paint for over 800ms while waiting for Google Fonts CDN responses.

2. Profiling & Diagnosing Root Causes

Using the Chrome DevTools Performance tab and Lighthouse under a simulated Fast 4G / 4x CPU slowdown, we isolated the exact render timeline. The hero image was being discovered late in the network waterfall because the browser had to first download, parse, and execute the CSS stylesheet before requesting the image.

3. Fix 1: Next/Image & Priority AVIF Assets

We replaced the background CSS image with Next.js <Image /> using the priority attribute and configured Next.js image optimization in next.config.ts for AVIF and WebP:

// next.config.ts
const nextConfig = {
  images: {
    formats: ['image/avif', 'image/webp'],
    deviceSizes: [640, 750, 828, 1080, 1200, 1920],
  },
};

Adding priority injects a high-priority <link rel="preload" as="image"> tag directly in the server-rendered HTML <head>, allowing the browser to fetch the hero asset before any JavaScript finishes parsing.

4. Fix 2: Dynamic Imports & Pruning Client JS

Offload non-critical client widgets (such as smooth scroll containers, particle canvases, or below-the-fold modals) using next/dynamic with ssr: false:

import dynamic from 'next/dynamic';

const ParticleBackground = dynamic(
  () => import('@/components/ParticleBackground'),
  { ssr: false }
);

This cut our initial main-thread JavaScript bundle by 42% (from 680KB to 395KB), freeing up the CPU to render DOM nodes instantly.

5. Fix 3: Zero-Layout-Shift Web Fonts

We migrated from external @import CSS font links to Next.js next/font/google. Next.js automatically downloads the font files at build time and hosts them locally alongside static assets with automatic size-adjust fallbacks, eliminating Cumulative Layout Shift (CLS) and FOIT (Flash of Invisible Text).

6. The Results: From 5.2s to 1.1s

BEFORE OPTIMIZATION

LCP: 5.2s
TTFB: 1.2s
CLS: 0.18
Lighthouse Score: 48/100

AFTER OPTIMIZATION

LCP: 1.1s (78% faster)
TTFB: 180ms
CLS: 0.001
Lighthouse Score: 99/100

Production Case Study

NextGen UI Landing Page — 60fps & Sub-Second LCP Showcase

Explore how responsive layouts, zero-layout-shift typography, and optimized asset pipelines were engineered into the live NextGen UI platform.

Related Topics & Technologies

#Next.js#Web Performance#Core Web Vitals#LCP#Frontend
Kowshik Valipireddy

Kowshik Valipireddy

Author

Full Stack Developer & AI Engineer

Full Stack Developer specializing in React, Next.js, TypeScript, Node.js, and AI workflows. Passionate about building fast, accessible, and SEO-optimized web experiences.

Recommended Articles

View all
kowshikvalipireddy@gmail.com