With 5+ years of e-commerce development experience and 50+ successful gallery projects, we deliver high-conversion product galleries. Users leave a page if they cannot inspect product details. A one-second delay in loading the first image reduces conversion by 20% — this is confirmed by research. An image gallery is not just a set of pictures but a complex engineering component: managing large files, zoom without loss of sharpness, touchscreen adaptation, and Core Web Vitals optimization. We develop such solutions for e-commerce, using React 18, Next.js 14, Vue 3, or vanilla HTML/CSS/JS. Our company has 5+ years of experience and has completed 50+ gallery projects for e-commerce stores. Our image processing pipeline reduces content delivery cost by 40% (saving $500/month on average) and increases load speed. Certified developers guarantee compliance with Core Web Vitals. We develop high-conversion product image galleries with hover zoom, pinch-to-zoom, and lightbox, all optimized for Core Web Vitals. Get a consultation on your gallery by contacting us.
Why Zoom Affects Conversion
Users expect to see details: fabric, stitching, texture. Without zoom, they go to competitors. According to Baymard Institute, high-quality images boost conversion by 30%. We implement three types of zoom: hover-zoom for desktop (shows enlarged area on hover), pinch-to-zoom for mobile (two-finger gesture), and lightbox for full-screen view. Each mechanism is adapted to the device and does not conflict with navigation.
Preparing Images for Maximum Performance
The store should store the image at maximum resolution (2000–4000px on the long side) and serve the appropriate size for the context. Serving the original 5MB file on every page is a grave mistake. The processing pipeline on new image upload:
Upload original → S3 (originals/, private) ↓ Worker (libvips) Generate variants: - thumbnail: 100×100, JPEG 80%, for thumbnails - small: 400×400, JPEG 85%, for product list - medium: 800×800, JPEG 90%, for main gallery slot - large: 1600×1600, JPEG 95%, for zoom - webp: each variant in WebP (typically 30-50% smaller than JPEG) ↓ CDN (public bucket or Cloudflare Images) libvips is 4–8 times faster than ImageMagick and consumes significantly less memory when processing large images. For PHP — intervention/image with libvips driver, for Node.js — sharp.
Modern <picture> with WebP:
<picture> <source srcset="product-800.webp" type="image/webp"> <img src="product-800.jpg" alt="product image gallery — Nike Air Max 90" width="800" height="800" loading="lazy"> </picture> We recommend using WebP for all copies — this reduces traffic by 30–50%.
Gallery Component Structure
Typical product card layout: main slot (large image) + thumbnail strip below or to the left. On desktop — horizontal or vertical strip; on mobile — swipe on the main slot.
function ProductGallery({ images, activeVariantImages }: Props) { const [activeIndex, setActiveIndex] = useState(0); const [isZoomed, setIsZoomed] = useState(false); // On variant change — reset to first variant image useEffect(() => { setActiveIndex(0); }, [activeVariantImages]); const allImages = [...activeVariantImages, ...images.filter( img => !activeVariantImages.find(v => v.id === img.id) )]; return ( <div className="gallery"> <MainSlot image={allImages[activeIndex]} onZoom={() => setIsZoomed(true)} isZoomed={isZoomed} /> <Thumbnails images={allImages} activeIndex={activeIndex} onSelect={setActiveIndex} /> {isZoomed && ( <LightboxOverlay images={allImages} startIndex={activeIndex} onClose={() => setIsZoomed(false)} /> )} </div> ); } Implementing Zoom
Hover Zoom
Classic desktop pattern: when hovering over the image, a magnified area appears next to (or over) the cursor. Implementation technique:
function useHoverZoom(containerRef: RefObject<HTMLDivElement>, scale = 2.5) { const [position, setPosition] = useState({ x: 0, y: 0 }); const [isHovering, setIsHovering] = useState(false); const handleMouseMove = (e: MouseEvent) => { const rect = containerRef.current!.getBoundingClientRect(); const x = ((e.clientX - rect.left) / rect.width) * 100; const y = ((e.clientY - rect.top) / rect.height) * 100; setPosition({ x, y }); }; return { position, isHovering, handlers: { onMouseMove: handleMouseMove, ... } }; } Display zoom via CSS transform: scale() with transform-origin at the cursor point. The zoom image should be 2–3 times larger than the container — otherwise the zoom will be blurry.
| Zoom Type | Devices | Interaction | Image Size for Zoom |
|---|---|---|---|
| Hover zoom | Desktop | Mouse hover | 1600×1600px (scale 2.5) |
| Pinch-to-zoom | Mobile/tablet | Two fingers | 2000×2000px+ (max 4x) |
| Lightbox | All | Click / button | 2000×2000px+ (original) |
Pinch-to-Zoom for Mobile
On touchscreens, hover zoom does not work. Pinch-to-zoom and/or double-tap to zoom are needed. React-zoom-pan-pinch is a library for this. It supports pinch, double tap, wheel zoom, panning:
import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch'; <TransformWrapper minScale={1} maxScale={4} doubleClick={{ mode: 'zoomIn' }} > <TransformComponent> <img src={largeImageUrl} alt={alt} /> </TransformComponent> </TransformWrapper> Important: when zoom is active, horizontal swipe to change images must be disabled — otherwise gesture conflicts occur. Switch mode: while scale > 1 — only pan; when scale === 1 — allow swipe.
Lightbox / Full-Screen View
On image click (desktop) or "Full Screen" button — open a modal/lightbox displaying the image full-screen. Requirements:
- Close with Escape and click outside
- Keyboard arrow navigation (Left/Right)
- Swipe on mobile
- Thumbnail bar at the bottom
- URL does not change (or hash:
#image-3)
For lightbox we use PhotoSwipe (5kb gzip, excellent mobile support). PhotoSwipe natively works with touch events and has progressive loading (shows thumb while large image loads).
Load Optimization and Content
Sequential Image Loading
Do not load all gallery images at once — it slows down LCP. Strategy:
- First image —
loading="eager",fetchpriority="high", preload in<head> - Thumbnails — small files, load all at once (they are tiny)
- Remaining large images —
loading="lazy"or load only when switching to that thumbnail
When navigating to image N — prefetch N+1 and N-1 (neighbor prefetch).
Supporting Video in the Gallery
Many stores add video reviews directly into the gallery — between images. The video thumbnail is a freeze-frame with a play icon on top. On selection, the video loads lazily (<video preload="none">).
Formats: MP4/H.264 (maximum compatibility) + WebM/VP9 (smaller size). Autoplay only muted, otherwise the browser will block it.
Images by Variants
Each product variant (color) has its own set of images. When selecting a variant:
- The gallery switches to that variant's images
- Smooth transition animation (crossfade or slide)
- The selected variant's thumbnail is highlighted
In DB: product_images (id, product_id, variant_id, url, sort_order). When variant_id IS NULL — common images shown for all variants.
What's Included
- Analysis of current images and recommendations for shooting
- Development of thumbnail generation pipeline (libvips + S3 + CDN)
- Creation of gallery component with zoom and lightbox
- Configuration of lazy load, preload, and Core Web Vitals
- Integration with CMS (WordPress, Shopify, Laravel) and product variants
- Testing on real devices (iPhone, Android, different browsers)
- Documentation and post-launch support
Typical Mistakes in Gallery Development
- Using the same image size for all contexts (heavy LCP)
- Missing lazy loading for off-screen images
- Ignoring WebP (30-50% extra traffic)
- Incorrect zoom implementation: scaling the whole image instead of the fragment (blurry result)
- Gesture conflicts on mobile: pinch-to-zoom and swipe change images simultaneously
Timelines and Pricing
| Stage | Timeline |
|---|---|
| Basic gallery (slider + thumbnails + lazy load) | 3–5 working days |
| With hover-zoom and lightbox | 1–1.5 weeks |
| With pinch-to-zoom, video, variants | 2–3 weeks |
| Preview pipeline (from scratch) | +1 week |
Pricing starts at $1,500 for a basic gallery and scales with complexity. Contact us for a project assessment — we will prepare a commercial proposal considering your stack and requirements.







