Nativ ui
Documentation

Images

Complete guide to optimizing web images - formats, sizes, loading strategies and Next.js best practices.

Overview

This playbook covers:

  • Choosing the right image format for each use case
  • Optimal sizes and resolutions (mobile/desktop)
  • Loading and smooth display strategies
  • Responsive images with srcset
  • Next.js specific optimizations

Image Formats

AVIF

The most performant format currently available.

Pros:

  • Best compression (30-50% lighter than WebP/JPEG)
  • Modern color management
  • Ideal for photos and complex visuals

Cons:

  • Slower encoding at build time
  • More CPU-intensive decoding

WebP

Excellent quality/size tradeoff.

Pros:

  • Very compact (much better than PNG/JPEG)
  • Fast decoding
  • Excellent browser support

Cons:

  • Slightly less efficient compression than AVIF

PNG

Reserved for UI elements only.

Pros:

  • Perfect for logos, icons, sharp transparencies
  • Lossless quality

Cons:

  • Catastrophic for photos/backgrounds (huge files)

SVG

For vector elements only.

Pros:

  • Tiny size for vector shapes
  • Perfectly scalable
  • Ideal for logos, patterns, flat illustrations

Cons:

  • Not suitable for photos or complex renders

Base64

Avoid for real images.

Usage:

  • Only for tiny placeholders (blur)
  • Avoids extra requests for tiny assets

Cons:

  • Bloats HTML/JS
  • No dedicated HTTP cache

Production Recommendation

AVIF (primary) → WebP (fallback) → JPEG (legacy)
  • Use AVIF as primary format with WebP fallback
  • Keep PNG only for UI assets or logos with transparency
  • Reserve base64 for very small placeholders only

Optimal Sizes

Desktop (backgrounds, hero images)

UsageWidthHeightTarget Size
Half-screen (~800px visible)1200-1600px900-1000px150-350 KB
Full screen1920-2400px1080-1200px200-400 KB

Mobile

UsageWidthHeightTarget Size
Full screen portrait750-1080px1200-1600px80-200 KB
Header/Hero750-1080px600-800px50-150 KB

Practical Examples

Desktop auth background : ~1600×1000 → 150-300 KB
Mobile auth background  : ~900×1600  → 80-150 KB

Loading and Display

Priority vs Lazy Loading

// Critical page (login) - use priority
<Image
  src="/auth-bg.avif"
  priority
  // ...
/>
 
// Secondary pages - lazy loading by default
<Image
  src="/signup-bg.avif"
  // no priority = lazy loading
/>

Rule: Only one priority image per critical page.

Blur Placeholder + Fade-in

'use client'
 
import Image from 'next/image'
import { useState } from 'react'
 
export function BackgroundImage({ src, alt }: { src: string; alt: string }) {
  const [isLoaded, setIsLoaded] = useState(false)
 
  return (
    <Image
      src={src}
      alt={alt}
      fill
      className={`object-cover transition-opacity duration-500 ${
        isLoaded ? 'opacity-100' : 'opacity-0'
      }`}
      placeholder="blur"
      blurDataURL="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ..."
      onLoadingComplete={() => setIsLoaded(true)}
    />
  )
}

Compression

Recommended pipeline:

  1. Export from Figma/Photoshop as high quality JPEG (80-90)
  2. Convert to AVIF/WebP with quality 50-70
  3. Tools: sharp, imagemin, Cloudinary, ImageKit

Target: Max 300 KB per desktop visual, less for mobile.

Responsive Images

Why use srcset?

  • Avoids over-downloading on mobile
  • Browser picks the right resolution
  • Next.js handles it automatically via sizes

Example with sizes

<Image
  src="/auth-bg.avif"
  alt="Background"
  fill
  className="object-cover"
  sizes="
    (max-width: 640px) 100vw,
    (max-width: 1024px) 50vw,
    50vw
  "
/>

sizes tells the browser the actual width of the image at each breakpoint, allowing Next.js to serve the right resolution.

Next.js Image (App Router)

Basic Configuration

import Image from 'next/image'
 
// Background with fill
<div className="relative h-screen">
  <Image
    src="/hero-bg.avif"
    alt="Hero background"
    fill
    priority
    className="object-cover"
    placeholder="blur"
    sizes="100vw"
  />
</div>

Remote Images (CDN)

// next.config.mjs
export default {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'cdn.example.com',
        pathname: '/images/**',
      },
    ],
  },
}

Automatic Formats

With Vercel Image Optimization, provide a high quality source (JPEG) and Next.js will serve AVIF/WebP automatically based on browser support.

Complete Example: Auth Layout

// app/(auth)/layout.tsx
import Image from 'next/image'
 
export default function AuthLayout({
  children
}: {
  children: React.ReactNode
}) {
  return (
    <div className="grid min-h-screen grid-cols-1 lg:grid-cols-2">
      {/* Desktop background */}
      <div className="relative hidden lg:block">
        <Image
          src="/auth-bg-desktop.avif"
          alt="Auth background"
          fill
          priority
          className="object-cover"
          placeholder="blur"
          sizes="(max-width: 1024px) 0px, 50vw"
        />
      </div>
 
      {/* Content + Mobile background */}
      <div className="relative flex items-center justify-center px-6 py-8">
        <div className="absolute inset-0 lg:hidden -z-10">
          <Image
            src="/auth-bg-mobile.avif"
            alt="Auth background mobile"
            fill
            className="object-cover"
            placeholder="blur"
            sizes="100vw"
          />
        </div>
        <div className="relative z-10 w-full max-w-md">
          {children}
        </div>
      </div>
    </div>
  )
}

Checklist

  • AVIF/WebP format used (no PNG for photos)
  • Sizes adapted to viewport (no 4K on mobile)
  • Size < 300 KB desktop, < 200 KB mobile
  • priority only on critical page image
  • sizes defined for responsive images
  • Blur placeholder for smooth loading
  • CSS fade-in for elegant transition