Optimagio

SvelteKit Image Optimization: Using Vite Plugins & APIs

Learn how to optimize images in SvelteKit using Vite plugins for build-time processing and API routes for dynamic transformations.

Optimagio Team 4 min read
SvelteKit Image Optimization: Using Vite Plugins & APIs

Images are often the largest assets on modern websites, significantly impacting loading times and Core Web Vitals. In SvelteKit, you have two powerful approaches to image optimization: build-time processing with Vite plugins and runtime transformation through API routes. This guide shows you how to implement both strategies effectively, covering everything from format conversion to responsive image handling.

Build-Time Optimization with Vite Plugins

Build-time optimization processes your images during the Vite build process, creating optimized versions that are served as static assets. This approach is ideal for images that are part of your codebase and don't change frequently.

  1. 1Install vite-imagetoolsAdd the vite-imagetools plugin to your project: npm install -D vite-imagetools
  2. 2Configure ViteAdd the plugin to your vite.config.js file and configure default transformations
  3. 3Import and use optimized imagesImport images with query parameters for format, width, and quality options
  4. 4Generate responsive srcsetsUse the plugin's built-in functionality to generate multiple sizes for responsive images
// vite.config.js
import { defineConfig } from 'vite'
import { imagetools } from 'vite-imagetools'

export default defineConfig({
  plugins: [
    imagetools({
      defaultDirectives: (url) => {
        if (url.searchParams.has('webp')) {
          return new URLSearchParams('format=webp&quality=80')
        }
        return new URLSearchParams('quality=80')
      }
    })
  ]
})
// Component usage
import heroImage from './hero.jpg?w=1200;800;400&format=webp'

// The imported image is an object with src and srcset
const { src, srcset } = heroImage

Runtime Optimization with API Routes

For dynamic images—such as user uploads, content from external APIs, or frequently changing assets—runtime optimization via SvelteKit API routes provides flexibility. This approach processes images on-demand while maintaining performance through caching.

Pros
  • Dynamic content supportHandles user-generated and external images
  • Flexible transformationsApply different optimizations based on request parameters
  • No rebuild requiredImages can change without rebuilding the entire application
Cons
  • Server processingRequires server resources for image processing
  • Response timeFirst request may be slower while image is processed
  • Caching complexityRequires careful caching strategy implementation
// src/routes/api/images/[transform]/[filename].js
import sharp from 'sharp'

export async function GET({ params }) {
  const { transform, filename } = params
  const [width, height, format] = transform.split('x')
  
  // Fetch original image (from storage, database, or external source)
  const imageBuffer = await fetchOriginalImage(filename)
  
  // Process with sharp
  const processedImage = await sharp(imageBuffer)
    .resize(parseInt(width), height ? parseInt(height) : null)
    .toFormat(format || 'webp')
    .toBuffer()

  return new Response(processedImage, {
    headers: {
      'Content-Type': `image/${format || 'webp'}`,
      'Cache-Control': 'public, max-age=31536000, immutable'
    }
  })
}

Implementing Responsive Images

Responsive images ensure users receive appropriately sized images for their viewport and device capabilities. Combine build-time optimization with responsive markup for the best results.

ApproachUse CaseImplementation
Resolution switchingDifferent screen sizessrcset with w descriptors
Art directionDifferent crop ratiospicture element with media queries
Format switchingBrowser capability supportpicture element with type attributes
<!-- Responsive image with format and resolution switching -->
<picture>
  <source 
    type="image/avif" 
    srcset="/api/images/800x450/avif/photo.jpg 800w,
            /api/images/1200x675/avif/photo.jpg 1200w"
    sizes="(max-width: 800px) 100vw, 1200px">
  <source 
    type="image/webp" 
    srcset="/api/images/800x450/webp/photo.jpg 800w,
            /api/images/1200x675/webp/photo.jpg 1200w"
    sizes="(max-width: 800px) 100vw, 1200px">
  <img 
    src="/api/images/800x450/jpeg/photo.jpg" 
    srcset="/api/images/800x450/jpeg/photo.jpg 800w,
            /api/images/1200x675/jpeg/photo.jpg 1200w"
    sizes="(max-width: 800px) 100vw, 1200px"
    alt="Responsive image example"
    loading="lazy">
</picture>

Caching Strategies for Optimized Images

Effective caching is crucial for performance. Build-time optimized images can use immutable caching, while runtime transformations benefit from content-based caching and CDN integration.

Choosing Between Build-Time and Runtime Optimization

The choice between build-time and runtime optimization depends on your specific use case. Here's when to use each approach:

Build-Time OptimizationUse for static site assets, marketing images, and content that changes infrequently. Provides best performance with zero runtime overhead.
Runtime OptimizationUse for user-generated content, dynamic images from APIs, and frequently changing assets. Offers flexibility but requires server resources.
Hybrid ApproachCombine both: optimize known images at build time, and use runtime optimization for dynamic content. This balances performance and flexibility.

Automate image optimization with Optimagio

Doing this by hand for every image does not scale. Optimagio optimizes and converts your images (WebP and AVIF) automatically across your API, web app, and CMS — so every page ships the smallest possible files without manual work. See plans and pricing →

FAQ

Frequently asked questions

What's the difference between build-time and runtime image optimization in SvelteKit?

Build-time optimization processes images during the Vite build process, creating optimized versions that are served as static assets. Runtime optimization uses API routes to transform images on-demand, making it suitable for user-generated or dynamic content.

Which image formats should I use for optimal performance?

Use WebP for broad browser compatibility and good compression, AVIF for superior compression where supported, and fall back to JPEG/PNG for older browsers. Modern formats can reduce file sizes by 25-50% compared to traditional formats.

How do I handle responsive images in SvelteKit?

Use the picture element with multiple source elements for different formats, and combine with srcset and sizes attributes for responsive sizing. Vite plugins can generate multiple sizes automatically during build.

Should I optimize all images at build time or runtime?

Optimize static images (like site assets) at build time for maximum performance. Use runtime optimization for dynamic content like user uploads or content from external APIs where images change frequently.

How can I cache optimized images effectively?

Set appropriate Cache-Control headers with long max-age values for static optimized images. For dynamic transformations, use content-based hashing in filenames and implement CDN caching for frequently accessed transformations.