Skip to main content
CodeRocket
Imageslowoptimization

Use image sprites where appropriate

rule · sprite-generation

Sprites reduce HTTP requests by combining multiple images, though modern alternatives often work better.

Code Example

CSS
/* Sprite image: icons.png (contains multiple icons in a grid) */
.icon {
  display: inline-block;
  width: 24px;
  height: 24px;
  background-image: url('icons.png');
  background-repeat: no-repeat;
}
 
.icon-home {
  background-position: 0 0;
}
 
.icon-settings {
  background-position: -24px 0;
}
 
.icon-user {
  background-position: -48px 0;
}
 
.icon-search {
  background-position: 0 -24px;
}

Why It Matters

Each image is an HTTP request—combining many small images into one sprite reduces requests, though modern HTTP/2 and SVG icons have reduced this need.

When to Use Sprites vs Alternatives

Use CaseRecommended Approach
UI iconsSVG sprite or icon font
Social media iconsSVG sprite
Small decorative imagesCSS sprite
Complex illustrationsIndividual SVG files
Photographic thumbnailsIndividual images with lazy loading

SVG Sprite (Modern Approach)

HTML
<!-- SVG sprite file (icons.svg) -->
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
  <symbol id="icon-home" viewBox="0 0 24 24">
    <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
  </symbol>
  <symbol id="icon-settings" viewBox="0 0 24 24">
    <path d="M19.14 12.94c.04-.31..."/>
  </symbol>
  <symbol id="icon-user" viewBox="0 0 24 24">
    <path d="M12 12c2.21 0 4-1.79..."/>
  </symbol>
</svg>
 
<!-- Usage -->
<svg class="icon" aria-hidden="true">
  <use href="icons.svg#icon-home"></use>
</svg>

React SVG Icon Component

TSX
interface IconProps {
  name: string
  size?: number
  className?: string
  title?: string
}
 
function Icon({ name, size = 24, className, title }: IconProps) {
  return (
    <svg
      width={size}
      height={size}
      className={`icon icon-${name} ${className || ''}`}
      aria-hidden={!title}
      role={title ? 'img' : undefined}
    >
      {title && <title>{title}</title>}
      <use href={`/icons.svg#icon-${name}`} />
    </svg>
  )
}
 
// Usage
<Icon name="home" size={24} />
<Icon name="settings" title="Settings" />

Generating CSS Sprites

JavaScript
// Using spritesmith
const Spritesmith = require('spritesmith')
const fs = require('fs')
const glob = require('glob')
 
const sprites = glob.sync('icons/*.png')
 
Spritesmith.run({ src: sprites }, (err, result) => {
  if (err) throw err
 
  // Save sprite image
  fs.writeFileSync('sprite.png', result.image)
 
  // Generate CSS
  let css = ''
  for (const [name, coords] of Object.entries(result.coordinates)) {
    const className = name.replace('icons/', '').replace('.png', '')
    css += `.icon-${className} {
  background-position: -${coords.x}px -${coords.y}px;
  width: ${coords.width}px;
  height: ${coords.height}px;
}\n`
  }
  fs.writeFileSync('sprite.css', css)
})

Inline SVG Sprite in HTML

TSX
// Include sprite in document (usually in layout)
function SvgSprite() {
  return (
    <svg
      xmlns="http://www.w3.org/2000/svg"
      style={{ position: 'absolute', width: 0, height: 0 }}
      aria-hidden="true"
    >
      <defs>
        <symbol id="icon-home" viewBox="0 0 24 24">
          <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
        </symbol>
        {/* More symbols */}
      </defs>
    </svg>
  )
}
 
// Then use anywhere
<svg className="icon">
  <use xlinkHref="#icon-home" />
</svg>

Retina CSS Sprites

CSS
/* 2x sprite for retina displays */
.icon {
  background-image: url('sprite.png');
  background-size: 200px 200px; /* Half of actual sprite size */
}
 
@media (-webkit-min-device-pixel-ratio: 2),
       (min-resolution: 192dpi) {
  .icon {
    background-image: url('sprite@2x.png');
  }
}

When NOT to Use Sprites

ScenarioBetter Alternative
Large imagesIndividual files with lazy loading
Frequently changing iconsIndividual SVG files
Icons needing color changesInline SVG or icon font
Simple shapesCSS-only (borders, shadows)

Support Notes

  • Image format and delivery behavior can vary by browser, CDN, and device characteristics, so verify the final bytes and rendered output on the supported browser matrix.
  • Add a fallback note when a modern format or loading behavior is not available for every required target browser.

Verification

  1. Check Network tab—sprite should load as single request
  2. Verify all icon positions display correctly
  3. Test retina sprite on high-DPI displays
  4. Compare load time vs individual images
  5. Check that SVG sprites scale properly at different sizes