Back to Rules
Next.js93% popularity

Next.js Image Optimization Best Practices

Use the Image component with proper sizing, formats, and loading strategies for maximum performance.

VercelUpdated Feb 28, 2024

Overview

Next.js Image component is a comprehensive solution for image optimization that addresses multiple performance concerns including bandwidth consumption, layout shift, and loading performance. Built on top of the modern picture element, it automatically serves appropriately sized images based on the viewing device and generates multiple formats including WebP and AVIF. Proper sizing is critical for Image component effectiveness. The width and height attributes define the aspect ratio and prevent Cumulative Layout Shift (CLS), one of Core Web Vitals metrics. Even with fill prop for responsive containers, the parent must have explicit dimensions or the container must use position: relative. The sizes attribute tells the browser which image variant to download based on viewport, preventing large images from being downloaded on small screens. The priority prop should be used for above-the-fold images that are critical for initial rendering. This adds preload links to the head and ensures the image loads before the browser's idle period, significantly improving Largest Contentful Paint (LCP). However, priority should be used sparingly since preloading all images eliminates the lazy loading benefits. Image formats should be considered carefully. WebP provides excellent compression with broad support, while AVIF offers even better compression but limited browser support. Next.js automatically serves AVIF to supported browsers and falls back to WebP for others. For images with transparency, WebP or PNG should be used; for photographs, JPEG with quality optimization is typically best. The placeholder prop with blur data URLs provides visual feedback during loading, improving perceived performance.

Code Example

.nextjsrules
import Image from 'next/image';
import Link from 'next/link';

export function ProjectCard({ project }: { project: Project }) {
  return (
    <Link href={project.href} className="project-card">
      <div className="image-wrapper">
        <Image
          src={project.thumbnail}
          alt={project.name + ' project thumbnail'}
          fill
          sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
          style={{ objectFit: 'cover' }}
          placeholder="blur"
          blurDataURL={project.blurHash}
        />
      </div>
      <div className="content">
        <h3>{project.name}</h3>
        <p>{project.description}</p>
      </div>
    </Link>
  );
}

export function HeroImage() {
  return (
    <div className="hero-container">
      <Image
        src="/hero-desktop.jpg"
        alt="Application dashboard overview"
        width={1200}
        height={800}
        priority
        quality={90}
        sizes="100vw"
        className="hero-image"
      />
      <Image
        src="/hero-mobile.jpg"
        alt="Application dashboard on mobile"
        width={400}
        height={600}
        priority
        quality={85}
        sizes="100vw"
        className="hero-image-mobile"
      />
    </div>
  );
}

More Next.js Rules

NEXTJS
98%

Next.js App Router Server Components First

Prioritize React Server Components for data fetching and static content. Client components only when interactivity is required.

server-componentsapp-routerperformance
'use server';

import { db } from '@/lib/database';
import { cache } from 'react';

export const getProjects = cache(async () => {
  return db.project...
Jan 15, 2024by Vercel Engineering
View Rule
NEXTJS
94%

Next.js Middleware Authentication

Implement authentication at the edge with Next.js Middleware for protected routes.

nextjsmiddlewareauthentication
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { jwtVerify } from 'jose';

const JWT_SECRET = new ...
Mar 8, 2024by Next.js Team
View Rule
NEXTJS
92%

Next.js Dynamic Metadata API

Use the Metadata API for SEO optimization with dynamic titles, descriptions, and OpenGraph images.

nextjsseometadata
import { Metadata, ResolvingMetadata } from 'next';
import { notFound } from 'next/navigation';
import { db } from '@/lib/db';
import { SchemaMarkup }...
Mar 18, 2024by Vercel
View Rule