This episode covers the next/image component and image optimization, static assets in the public folder, handling video and audio with lazy loading, and best practices for responsive images and overall web performance.

Images and media are the biggest contributors to web page size. An unoptimized photo can add hundreds of kilobytes and slow down load time — directly affecting user experience and SEO ranking.
Episode 9 covers the next/image component and Next.js's built-in optimization system, static assets in the public folder, handling video and audio with lazy loading, and best practices for responsive images and web performance.
The Image component from next/image optimizes images automatically: conversion to modern formats like WebP and AVIF, resizing to match screen size, and built-in lazy loading:
import Image from "next/image"
export default function Hero() {
return (
<Image
src="/hero.jpg"
alt="Ilustrasi produk"
width={1200}
height={630}
priority
/>
)
}The priority prop on the image above tells Next.js that this image is important and should load earlier — suitable for the largest image visible first (LCP). Always provide a descriptive alt for accessibility.
For images that adapt to their container, use fill together with sizes so the browser picks the right size per viewport:
<Image
src="/banner.png"
alt="Banner promosi"
fill
sizes="(max-width: 768px) 100vw, 50vw"
className="object-cover"
/>The prop sizes="(max-width: 768px) 100vw, 50vw" tells Next.js what size the image needs on small and large screens, producing a lighter response.
Every file in the public folder is served directly from the root URL. A common structure:
public/
favicon.ico
logo.png
images/
hero.jpgThe file public/images/hero.jpg is available at /images/hero.jpg. Assets here don't go through Next.js optimization — for images that need optimization, put them inside the project and import them directly, or use the Image component.
If assets are served from a separate CDN, use the assetPrefix configuration option in next.config.mjs. This feature prepends a URL prefix to all referenced assets, useful when you serve JavaScript and CSS from your own CDN domain.
Video and audio use standard HTML elements. The key principle is lazy loading: don't download media until it's needed. Give videos preload="metadata" so only metadata loads when the page first opens, and control it with the loading attribute:
<video
controls
preload="metadata"
src="/demo.mp4"
poster="/demo-poster.jpg"
>
Browser kalian tidak mendukung video.
</video>The preload="metadata" on the video above delays the download of the full content. General media rules: consider a streaming provider for large files, compress audio into lightweight formats like MP3 or AAC, and always provide a poster for videos.
Responsive images mean serving the right size per screen — don't send a 2000-pixel desktop image to mobile users. The Image component handles this via the sizes attribute, while the automatically generated srcSet provides several variants. This reduces the data sent and speeds up load time.
Apply this strategy: images visible first get priority, images below get built-in lazy loading, and every image has an alt and explicit dimensions to avoid layout shift (CLS). This combination directly improves Core Web Vitals — metrics we'll measure in episodes 15 and 22.
Here's what to take away:
In the next episode, episode 10, we'll discuss forms and validation — handling forms in React components, client-side validation with React Hook Form, server-side validation and submission to an API, and form accessibility with good UX feedback. Your user interactions will be polished until mature.