Last updated: February 5, 2025

<span aria-hidden="true" id="building-an-image-optimization-pipeline-with-a-cdn"></span>

# Building an image optimization pipeline with a CDN

![Kevin van Zonneveld](/assets/images/teammates/avatar-kvz-4.jpg?dpl=dpl_B2d4XACVUtA1h8m6kRxZhWsda77Q)

#### Kevin van Zonneveld

Co-founder · Amsterdam, The Netherlands · Show bio

[](https://x.com/kvz)[](https://github.com/kvz)

Image optimization is vital for modern web performance. In this post, we explore how to set up an image optimization pipeline using a Content Delivery Network (CDN) to ensure your images are automatically optimized and delivered quickly. The techniques demonstrated here apply regardless of the image optimization provider you choose.

<span aria-hidden="true" id="understanding-image-cdns"></span>

## Understanding image CDNs

An Image CDN is a specialized content delivery network that serves images from edge servers close to end users while performing real-time optimizations. Modern Image CDNs automatically detect browser support and serve next-generation formats such as WebP and AVIF. Key features include:

* **Next-gen format delivery** with automatic browser support detection
* **Responsive image generation** for various device sizes and pixel densities
* **Quality optimization** using perceptual quality algorithms
* **Smart compression** based on image content and format
* **Edge caching** with instant purge capabilities
* **DDoS protection** and enhanced security

<span aria-hidden="true" id="choosing-an-image-optimization-provider"></span>

## Choosing an image optimization provider

Multiple specialized providers offer modern image optimization solutions. Here is a brief comparison of popular options:

* **Cloudflare Images**: Leverages Cloudflare's global network and edge computing.
* **Cloudinary**: Offers advanced image processing with AI-based optimizations.
* **ImageKit**: Features a developer-friendly API for real-time image transformations.
* **Bunny CDN**: Provides cost-effective image delivery with widespread geographic coverage.
* **Fastly Image Optimizer**: Targets enterprise-grade image processing with robust performance.

For this guide, we use Cloudflare Images as an example, although the concepts apply to all providers.

<span aria-hidden="true" id="leveraging-azure-front-door-for-image-delivery"></span>

## Leveraging Azure Front Door for image delivery

Azure Front Door is a modern alternative to traditional CDNs, offering global load balancing and dynamic site acceleration. Integrating Azure Front Door into your image optimization pipeline can provide enhanced security, faster content delivery, and seamless integration with other Azure services. For more details, refer to the[Azure Front Door documentation⁠](https://learn.microsoft.com/en-us/azure/frontdoor/) and the[migration guide⁠](https://learn.microsoft.com/en-us/azure/frontdoor/migrate-from-cdn).

<span aria-hidden="true" id="setting-up-image-optimization"></span>

## Setting up image optimization

Below is a TypeScript interface for image optimization options along with a synchronous function to generate an optimized image URL. In more advanced scenarios, you might fetch image metadata, but this example focuses on URL construction.

```typescript
interface ImageOptimizationOptions {
  width?: number
  height?: number
  quality?: number
  format?: 'auto' | 'webp' | 'avif' | 'jpeg' | 'png'
  fit?: 'cover' | 'contain' | 'fill'
  dpr?: number
}

function getOptimizedImageUrl(path: string, options: ImageOptimizationOptions = {}): string {
  try {
    const cdnEndpoint = 'https://imagedelivery.net/your-account'
    const params = new URLSearchParams()
    if (options.width) params.append('width', options.width.toString())
    if (options.height) params.append('height', options.height.toString())
    if (options.quality) params.append('quality', options.quality.toString())
    if (options.format) params.append('format', options.format)
    if (options.fit) params.append('fit', options.fit)
    if (options.dpr) params.append('dpr', options.dpr.toString())
    const url = `${cdnEndpoint}${path}?${params.toString()}`
    new URL(url) // Validate URL
    return url
  } catch (error) {
    console.error('Error generating optimized image URL:', error)
    throw error
  }
}

```

<span aria-hidden="true" id="implementing-responsive-images"></span>

## Implementing responsive images

Create a React component that handles responsive images by generating source sets for multiple formats. This example uses the synchronous URL generator from above:

```tsx
interface ResponsiveImageProps {
  src: string;
  alt: string;
  sizes: string;
  className?: string;
  loading?: 'lazy' | 'eager';
  widths: number[];
}

function ResponsiveImage({
  src,
  alt,
  sizes,
  className,
  loading = 'lazy',
  widths,
}: ResponsiveImageProps) {
  const generateSrcSet = (format: string) => {
    return widths
      .map((width) => {
        const url = getOptimizedImageUrl(src, { width, format });
        return `${url} ${width}w`;
      })
      .join(', ');
  };

  return (
    <picture>
      <source type="image/avif" srcSet={generateSrcSet('avif')} sizes={sizes} />
      <source type="image/webp" srcSet={generateSrcSet('webp')} sizes={sizes} />
      <img
        src={getOptimizedImageUrl(src, {
          width: Math.max(...widths),
          format: 'jpeg',
        })}
        alt={alt}
        className={className}
        loading={loading}
        onError={(e) => {
          const img = e.currentTarget;
          img.onerror = null;
          img.src = '/path/to/fallback-image.jpg';
        }}
      />
    </picture>
  );
}

```

<span aria-hidden="true" id="monitoring-performance"></span>

## Monitoring performance

Implement comprehensive performance monitoring using the Web Vitals API along with a robust PerformanceObserver implementation that checks for browser support and handles errors gracefully:

```typescript
import { onLCP, onFID, onCLS } from 'web-vitals'

function sendToAnalytics({ name, value, id }: { name: string; value: number; id: string }) {
  const body = JSON.stringify({ name, value, id })
  if (navigator.sendBeacon) {
    navigator.sendBeacon('/analytics', body)
  } else {
    fetch('/analytics', { body, method: 'POST', keepalive: true })
  }
}

function initializePerformanceMonitoring() {
  try {
    onLCP(sendToAnalytics)
    onFID(sendToAnalytics)
    onCLS(sendToAnalytics)
  } catch (error) {
    console.error('Error initializing web vitals:', error)
  }

  if ('PerformanceObserver' in window) {
    try {
      const observer = new PerformanceObserver((list) => {
        list.getEntriesByType('resource').forEach((entry) => {
          if (entry.initiatorType === 'img') {
            sendToAnalytics({
              name: 'image-load',
              value: entry.duration,
              id: entry.name,
            })
          }
        })
      })
      observer.observe({ entryTypes: ['resource'] })
    } catch (error) {
      console.error('PerformanceObserver error:', error)
    }
  }
}

```

<span aria-hidden="true" id="security-considerations"></span>

## Security considerations

Secure image delivery is paramount. Below is an example demonstrating how to generate signed URLs and set appropriate security headers. Note that functions such as `getSigningKey()` and`getCdnEndpoint()` are assumed to be defined elsewhere in your environment.

```typescript
interface SecurityOptions {
  expiresIn?: number
  allowedDomains?: string[]
}

async function getSecureImageUrl(
  path: string,
  options: ImageOptimizationOptions & SecurityOptions = {},
): Promise<string> {
  const { expiresIn = 3600 } = options
  const timestamp = Math.floor(Date.now() / 1000) + expiresIn

  // Generate HMAC signature using the Web Crypto API
  const key = await getSigningKey()
  const message = `${path}${timestamp}`
  const signatureBuffer = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(message))
  const hexSignature = Array.from(new Uint8Array(signatureBuffer))
    .map((b) => b.toString(16).padStart(2, '0'))
    .join('')

  const params = new URLSearchParams()
  if (options.width) params.append('width', options.width.toString())
  if (options.height) params.append('height', options.height.toString())
  if (options.quality) params.append('quality', options.quality.toString())
  if (options.format) params.append('format', options.format)
  if (options.fit) params.append('fit', options.fit)
  if (options.dpr) params.append('dpr', options.dpr.toString())
  params.append('expires', timestamp.toString())
  params.append('signature', hexSignature)

  return `${getCdnEndpoint()}${path}?${params.toString()}`
}

// Set security headers for server responses
const securityHeaders = {
  'Content-Security-Policy': "img-src 'self' *.imagedelivery.net",
  'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
  'X-Content-Type-Options': 'nosniff',
}

```

<span aria-hidden="true" id="best-practices"></span>

## Best practices

1. **Optimize for Core Web Vitals**
   * Set explicit width and height attributes on images to prevent cumulative layout shift (CLS) and improve Largest Contentful Paint (LCP).
   * Preload critical images and use responsive techniques to ensure fast rendering.
   * Leverage modern monitoring tools to track web vitals.
2. **Select Modern Image Formats**
   * Serve AVIF images with a WebP fallback using the `<picture>` element.
   * Consider progressive JPEGs for larger images and adjust quality settings based on content.
3. **Implement Effective Caching**
   * Use stale-while-revalidate caching to deliver up-to-date images while refreshing in the background.
   * Version your assets and set appropriate cache Time-To-Live (TTL) values.
4. **Enhance Security**
   * Use signed URLs to protect your images.
   * Set strict Content Security Policy (CSP) headers and implement DDoS protection measures.
   * Enforce rate limiting on critical endpoints.
5. **Ensure Robust Error Handling**
   * Provide graceful fallbacks for image loading errors.
   * Monitor error rates and utilize placeholder images during loading or failure events.

<span aria-hidden="true" id="conclusion"></span>

## Conclusion

Implementing an image optimization pipeline with a CDN significantly enhances web performance and user experience. By leveraging modern image formats, integrating robust performance monitoring, and enforcing stringent security measures, you can deliver optimized images efficiently and securely. For advanced file processing and transformation needs, consider exploring Transloadit's capabilities with integrations such as Uppy and Tus.

\#web-performance#cdn#image-optimization#content-delivery-service

### 👩‍💻 Join 20k+ developers

Sign up for our [monthly newsletter](/newsletters.md) to receive direct links to 3 exclusive tech — and 2 product updates. No less, no more.

Your email:

Get access

## File uploading and encoding. Made simple.

Transloadit streamlines file handling for developers, trusted by brands like Coursera and The New York Times. We’re known for a reliable API, top-notch support, and a strong commitment to open source, with projects like [Uppy⁠](https://uppy.io) and [Tus⁠](https://tus.io) setting standards in file processing.

[Sign up](/c/)[Book a Demo](https://survey.typeform.com/to/kRg47Xi5)

No credit card needed · 5 GB included in the free plan

Cancel anytime
