Image Optimization w Next.js
next/image, WebP/AVIF z sharp, Cloudinary CDN, lazy loading z IntersectionObserver i SVG optymalizacja przez SVGR.
6 narzędzi optymalizacji obrazów — porównanie
next/image, Cloudinary, Imgix, sharp, Bunny.net i Plaiceholder — typ, automatyczny WebP, CDN i zastosowanie.
| Narzędzie | Typ | Auto WebP | CDN | Kiedy |
|---|---|---|---|---|
| next/image | Wbudowany Next.js | Tak | Self-hosted /_next/image | Next.js projekty — default wybór |
| Cloudinary | Image CDN + AI | Tak (f_auto) | Global CDN | E-commerce, AI crop, video+image |
| Imgix | Image CDN | Tak (auto) | Global CDN | Developer-friendly CDN, srcset |
| sharp (Node.js) | Server-side processor | Manualne | Brak (processing) | Self-hosted, API routes, build pipeline |
| Bunny.net Optimizer | CDN + Optymalizacja | Tak | Global CDN | Tani CDN, Next.js lub custom |
| Plaiceholder | Blur placeholder gen | Nie | Brak | Generuj blur dataURL dla next/image |
Często zadawane pytania
Co to jest next/image i jak działa optymalizacja obrazów?
next/image (Next.js wbudowany): automatyczna optymalizacja obrazów. Lazy loading by default. Blur placeholder. Responsive sizes. Automatyczna konwersja do WebP/AVIF. Rozmiar na żądanie przez API /_next/image. import Image from 'next/image'. Image src='/hero.jpg' alt='Hero' width={800} height={600}. Fill mode: Image src fill className='object-cover' — zajmuje kontener. Wymagany: container z position: relative. Priority prop: Image priority — LCP image. Brak lazy loading. Preload w head. Używaj tylko dla Above the Fold. sizes prop: sizes='(max-width: 768px) 100vw, 50vw'. Informuje przeglądarkę o rozmiarze. Generuje srcset. Optymalizacja: automatyczny WebP dla obsługujących. AVIF jeśli skonfigurowany. Rozmiar dopasowany do sizes. Sharp (npm install sharp): szybszy image processor. Zalecany w produkcji. Fallback: wbudowany bez sharp. Remote images: remotePatterns w next.config.js. {hostname: 'example.com', pathname: '/images/**'}. Wymaga whitelist dla bezpieczeństwa. Local images: import img from './photo.jpg'. Automatyczne width/height (statyczny import). Blur placeholder: placeholder='blur'. blurDataURL — base64 mini. Statyczne import: automatyczne. Remote: musisz podać blurDataURL. Generuj: plaiceholder library. unoptimized prop: pomiń optymalizację. Dla GIF/SVG animowanych. Loader: custom image loader dla CDN.
WebP, AVIF i nowoczesne formaty obrazów — jak konwertować?
Formaty obrazów: JPEG: stary standard. Lossy. Dobry dla zdjęcia. PNG: lossless. Alfa kanał. Większy niż JPEG. WebP (Google, 2010): 25-34% mniejszy niż JPEG. Lossless i lossy. Alfa kanał. Wsparcie: 95% przeglądarek. AVIF (Alliance for Open Media, 2019): 20-50% mniejszy niż WebP. Lossy i lossless. HDR support. Wsparcie: Chrome, Firefox, Safari 16+ (2022). Lepsza jakość przy tym samym rozmiarze. JPEG XL: przyszły standard. Lepszy od AVIF. Wsparcie: ograniczone (Chrome eksperymentalny). picture element: source type='image/avif' srcset='image.avif'. source type='image/webp' srcset='image.webp'. img src='image.jpg' alt='fallback'. Hierarchia: AVIF -> WebP -> JPEG. sharp library (Node.js): const sharp = require('sharp'). sharp('input.jpg').webp({quality: 80}).toFile('output.webp'). sharp('input.jpg').avif({quality: 50}).toFile('output.avif'). Batch conversion: glob('*.jpg') + sharp. Build pipeline: vite-plugin-imagemin, next/image (automatyczny). Squoosh CLI: @squoosh/cli. squoosh-cli --avif {} input.jpg. Batch optimizacja. imagemin-webp, imagemin-avif: webpack/gulp plugins. Jakość vs rozmiar: AVIF quality 40-60 = JPEG quality 80-90. WebP quality 70-85 = JPEG quality 80-90. Subjectywne — testuj dla contentu. Responsive images: srcset + sizes w HTML. next/image automatycznie generuje srcset. Lazy loading native: img loading='lazy'. Powyżej fold: loading='eager' lub bez atrybutu.
Cloudinary, Imgix i CDN do optymalizacji obrazów?
Cloudinary: Image/Video CDN + transformacje on-the-fly. URL-based transformacje: .../c_fill,w_800,h_600,f_auto,q_auto/image.jpg. f_auto — automatyczny format (WebP/AVIF). q_auto — automatyczna jakość. c_fill, c_crop, c_scale — crop modes. Smart crop (AI): g_auto — automatyczne centrowanie. g_face — twarz wyśrodkowana. Instalacja: @cloudinary/next. CldImage komponent (Community Cloudinary). Upload: Unsigned uploads dla userów. Signed uploads dla bezpieczeństwa. Transformacje: ograniczyć widgety, overlays. AI features: generative fill, background removal. Imgix: podobne do Cloudinary. URL transformacje. ix-react package. Doskonały srcset support. Predykowalny cennik. Mniej AI features. Bunny.net Stream + CDN: media CDN. Video + Image CDN. Mniejszy koszt niż Cloudinary. Bunny Optimizer: automatyczna optymalizacja. next/image z Cloudinary: next.config.js loader: 'custom'. images.loaderFile: './cloudinary-loader.js'. Lub: CldImage z next-cloudinary. Lokalna optymalizacja (bez CDN): sharp w API route. Generuj rozmiary w build time. Serwuj z /public. Plaiceholder: generuj blur placeholder. import {getPlaiceholder} from 'plaiceholder'. const {base64} = await getPlaiceholder('/photo.jpg'). Image CDN wybór: Cloudinary — max features, AI. Imgix — developer-friendly, wydajny. Bunny.net — tani, CDN-first. Uploadthing — upload dla Next.js (nie CDN optymalizacji). Własne S3 + CloudFront — enterprise, kontrola.
Lazy loading, Intersection Observer i priorytetyzacja obrazów?
Lazy loading natywne: img loading='lazy'. Działa w wszystkich major browsers (Chrome 77+, Firefox 75+, Safari 15.4+). Polyfill: lazysizes dla starszych. next/image: lazy by default. priority prop = eager loading. IntersectionObserver (JavaScript): const observer = new IntersectionObserver((entries) => {entries.forEach(entry => {if (entry.isIntersecting) {const img = entry.target; img.src = img.dataset.src; observer.unobserve(img)}})}). observer.observe(document.querySelectorAll('img[data-src]')). Szczegóły: rootMargin: '50px' — załaduj 50px przed viewport. threshold: 0.1 — 10% widoczności. useIntersectionObserver hook: useState(false). useRef na element. useEffect(() => observer.observe(ref.current)). Gdy intersection: setIsVisible(true). Renderuj Image dopiero gdy visible. React: react-intersection-observer package. useInView hook. inView — boolean. Fetch on demand. Image priority hierarchy: LCP image: loading='eager' + fetchpriority='high'. Above-fold: loading='eager'. Below-fold: loading='lazy' (default). Preload LCP: link rel='preload' as='image' href='/hero.webp'. imagesizes + imagesrcset dla responsive. fetchpriority='high' na img (nowy atrybut). Cumulative Layout Shift (CLS): zawsze podawaj width i height. Lub aspect-ratio w CSS. fill mode w next/image. Image skeleton: placeholder podczas ładowania. bg-gray-200 animate-pulse (Tailwind). Transition po załadowaniu: onLoadingComplete callback (next/image). opacity-0 -> opacity-100 przy load.
SVG optymalizacja i SVGR — jak używać SVG w React?
SVG w React — opcje: img src='icon.svg' — prosty, nie styleable przez CSS. background-image: url('icon.svg') — CSS. Inline SVG w JSX: pełna kontrola, CSS styleable, dostęp do każdej ścieżki. SVGR: konwertuj SVG do React komponentu. @svgr/webpack, @svgr/vite. import {ReactComponent as Icon} from './icon.svg'. Albo: import Icon from './icon.svg?react' (Vite z plugin). SVG jako React component: pełna kontrola props. currentColor — dziedzicz kolor od CSS. width/height props. className, style. SVGO: optymalizacja SVG plików. svgo CLI: svgo icon.svg. Usuwa zbędne atrybuty, komentarze, metadata. Reduce rozmiar 50-70%. SVGOMG (online): wizualna optymalizacja. Lucide React / Heroicons: gotowe icon libraries. Tree-shakeable. Małe rozmiary. import {ChevronDown} from 'lucide-react'. Kiedy inline SVG: ikony potrzebują animacji. currentColor (dziedziczenie koloru). CSS hover styles. Dostępność (aria-label). Kiedy img src: duże SVG ilustracje. Brak potrzeby interakcji. Lepszy cache. Sprite SVG: jeden plik z symbolami. use href='#icon-name'. HTTP/2 — mniejsze korzyści niż HTTP/1. Icon system: single SVG file + use. Custom SVG animations: CSS @keyframes na SVG elements. stroke-dasharray trick — path drawing. Lub Framer Motion na SVG komponentach. motion.path pathLength={0 do 1}. react-spring useSpring dla SVG props.
Powiązane artykuły
Skontaktuj się z nami
Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.
Wyślij zapytanie
Telefon
+48 790 814 814
Pon-Pt: 9:00 - 18:00
adam@fotz.pl
Odpowiadamy w ciągu 24h
Adres
Plac Wolności 16
61-739 Poznań
Godziny pracy
Wolisz porozmawiać?
Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.
Zadzwoń teraz