Topic 12 / 13

Images, Performance & Optimization

~9 min read  //  Next.js Series  //  Coding India

next/image — Use It for Every Image

The Image component resizes, converts to WebP/AVIF, lazy-loads, and reserves space (no layout shift) automatically:

import Image from "next/image";
import hero from "@/public/hero.png";        // static import — dimensions known

<Image src={hero} alt="Dashboard preview" priority />

// remote images need explicit dimensions…
<Image
  src={course.thumbnail}
  alt={course.title}
  width={640}
  height={360}
/>

// …or fill a sized container (thumbnails, covers)
<div style={{ position: "relative", aspectRatio: "16/9" }}>
  <Image src={course.thumbnail} alt="" fill style={{ objectFit: "cover" }} />
</div>

Rules: priority on the above-the-fold hero (preloads it — biggest LCP win), accurate sizes for responsive grids, and remote hosts whitelisted in config:

// next.config.mjs
export default {
  images: {
    remotePatterns: [{ protocol: "https", hostname: "i.ytimg.com" }],
  },
};

Ship Less JavaScript

  • Server components by default — every component without "use client" is free.
  • Push “use client” to the leaves — a client button, not a client page.
  • Dynamic-import heavy widgets:
import dynamic from "next/dynamic";

const Chart = dynamic(() => import("@/components/Chart"), {
  loading: () => <Skeleton />,
  ssr: false,             // browser-only libs (canvas, maps)
});

Find what’s heavy with the analyzer:

npm install @next/bundle-analyzer
ANALYZE=true npm run build      # opens a treemap of every chunk

Stream the Slow Parts

Don’t let one slow query block the page — Suspense boundaries (data-fetching topic) plus loading.js give instant shells with content streaming in. Audit any page that “feels slow”: usually one await is serialising everything.

Core Web Vitals — What to Watch

  • LCP (largest contentful paint, < 2.5s) — fixed by priority images, streaming, static rendering.
  • CLS (layout shift, < 0.1) — fixed by next/image dimensions and next/font.
  • INP (interaction latency, < 200ms) — fixed by shipping less JS and avoiding giant client components.

Measure with Lighthouse (DevTools), npm run build‘s route-size table, and Vercel Analytics in production. The framework defaults already optimise hard — most regressions come from accidental "use client" sprawl and unoptimised images, both now visible to you.