From harness-claude
Optimizes SVGs with SVGO, guides delivery method selection (inline, sprite, external), and builds accessible, performant icon systems.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:perf-svg-optimizationThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Master SVG optimization — automated minification with SVGO, inline versus external delivery trade-offs, SVG sprite sheet systems, accessibility patterns, rendering performance for complex vector graphics, and icon system architecture.
Master SVG optimization — automated minification with SVGO, inline versus external delivery trade-offs, SVG sprite sheet systems, accessibility patterns, rendering performance for complex vector graphics, and icon system architecture.
Optimize SVGs with SVGO. SVGO removes editor metadata, simplifies paths, and reduces file size by 30-80%:
# Install and run SVGO
npx svgo icon.svg -o icon.min.svg
# Batch optimize a directory
npx svgo -f src/icons/ -o dist/icons/
# Show detailed savings
npx svgo icon.svg --pretty --indent=2
// svgo.config.js — recommended configuration
module.exports = {
multipass: true,
plugins: [
'preset-default',
'removeDimensions', // use viewBox instead of width/height
'sortAttrs',
{
name: 'removeAttrs',
params: { attrs: ['data-name', 'class'] }, // remove editor cruft
},
{
name: 'preset-default',
params: {
overrides: {
removeViewBox: false, // keep viewBox for scalability
cleanupIds: {
minify: true,
remove: false, // keep IDs for sprite references
},
},
},
},
],
};
Choose the right delivery method. Each approach has specific trade-offs:
Method | Cacheable | Styleable | HTTP Requests | HTML Size
-----------------|-----------|-----------|---------------|----------
Inline SVG | No | Full CSS | 0 | Increases
External <img> | Yes | None | 1 per icon | Minimal
SVG sprite <use> | Yes | Limited | 1 total | Minimal
CSS background | Yes | None | 1 per icon | Minimal
Data URI | No | None | 0 | Increases
Inline SVG for icons that need CSS styling (color, hover states) and appear above the fold. SVG sprites for icon systems with many icons across the site. External <img> for complex illustrations that benefit from caching.
Build an SVG sprite sheet. Combine icons into a single file referenced via <use>:
# Generate sprite with svg-sprite
npx svg-sprite --symbol --symbol-dest=dist --symbol-sprite=icons.svg src/icons/*.svg
<!-- icons.svg sprite file -->
<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
<symbol id="icon-search" viewBox="0 0 24 24">
<path d="M15.5 14h-.79l-.28-.27A6.47..." />
</symbol>
<symbol id="icon-close" viewBox="0 0 24 24">
<path d="M19 6.41L17.59 5 12 10.59..." />
</symbol>
</svg>
<!-- Reference icons anywhere in the page -->
<svg width="24" height="24" aria-hidden="true">
<use href="/icons.svg#icon-search"></use>
</svg>
Make SVGs accessible. Icons need proper ARIA attributes depending on their role:
<!-- Decorative icon (next to text label): hide from screen readers -->
<button>
<svg width="20" height="20" aria-hidden="true" focusable="false">
<use href="#icon-search"></use>
</svg>
Search
</button>
<!-- Informational icon (no visible label): provide accessible name -->
<button aria-label="Search">
<svg width="20" height="20" role="img" aria-label="Search" focusable="false">
<use href="#icon-search"></use>
</svg>
</button>
<!-- Complex illustration: use title and desc -->
<svg role="img" aria-labelledby="chart-title chart-desc">
<title id="chart-title">Revenue Growth 2024</title>
<desc id="chart-desc">Bar chart showing 23% year-over-year revenue growth</desc>
<!-- chart paths -->
</svg>
Optimize complex SVGs for rendering performance. SVGs with thousands of paths cause layout and paint cost:
<!-- Contain rendering cost of complex SVGs -->
<div style="contain: layout paint; will-change: transform;">
<svg viewBox="0 0 1000 1000">
<!-- complex illustration with many paths -->
</svg>
</div>
<!-- Simplify paths: reduce control points -->
<!-- Before: <path d="M 10.123456 20.789012 C 30.111111..."> -->
<!-- After: <path d="M 10.1 20.8 C 30.1..."> -->
// SVGO: reduce path precision
module.exports = {
plugins: [
{
name: 'preset-default',
params: {
overrides: {
cleanupNumericValues: { floatPrecision: 1 },
convertPathData: { floatPrecision: 1 },
},
},
},
],
};
Implement an icon component for consistent delivery. Abstract the sprite reference into a reusable component:
interface IconProps {
name: string;
size?: number;
className?: string;
title?: string;
}
function Icon({ name, size = 24, className, title }: IconProps) {
const hasTitle = Boolean(title);
return (
<svg
width={size}
height={size}
className={className}
role={hasTitle ? 'img' : undefined}
aria-label={hasTitle ? title : undefined}
aria-hidden={hasTitle ? undefined : true}
focusable="false"
>
{hasTitle && <title>{title}</title>}
<use href={`/icons.svg#icon-${name}`} />
</svg>
);
}
// Usage
<Icon name="search" />
<Icon name="close" title="Close dialog" />
Remove embedded raster images and fonts. Design tools sometimes embed base64-encoded PNGs or font subsets inside SVGs:
# Find SVGs with embedded images
grep -rl 'image.*base64' src/icons/
grep -rl '<font' src/icons/
# These need to be re-exported from the design tool
# without "include images" or "outline fonts" options
Icon fonts (Font Awesome, Material Icons) were the standard icon delivery method before SVG systems matured. SVGs are superior in every dimension: per-icon loading (icon fonts are all-or-nothing), multi-color support, CSS animation control, accessibility (icon fonts use pseudo-elements that screen readers handle inconsistently), and rendering precision (icon fonts suffer from anti-aliasing artifacts at certain sizes). The only advantage of icon fonts is simpler setup — a single CSS include.
GitHub's Octicons icon system uses inline SVGs for above-the-fold icons (navigation, status indicators) and an SVG sprite for the full icon set. Each icon is optimized with SVGO to under 500 bytes. The sprite file (~15KB for 250+ icons) is loaded once and cached with a content-hashed filename. Icons use aria-hidden="true" when adjacent to text labels and aria-label when standalone. The Icon React component enforces these accessibility patterns, making incorrect usage a lint error. Total icon overhead per page: ~2KB inline + 15KB sprite (cached).
Figma exports SVGs with editor metadata (data-name, Figma-specific attributes) that double file size. A production pipeline runs: (1) Export from Figma via API, (2) SVGO with custom config that strips Figma metadata and reduces precision to 1 decimal, (3) Generate sprite sheet with svg-sprite, (4) Generate TypeScript icon name union type from the sprite for type safety. This automated pipeline runs in CI when designers push to the Figma file, ensuring icons are always optimized and type-safe.
Inlining large SVGs in every page. A 20KB inline SVG illustration on every page adds 20KB to every HTML response and is never cached. Use <img> or <object> for illustrations larger than 2KB so the browser can cache them.
Using SVGs with embedded raster images. An SVG containing a base64-encoded PNG is worse than serving the PNG directly: larger file, no responsive image benefits, and the SVG wrapper adds parse overhead.
Animating SVG properties that trigger layout. Animating width, height, x, y, or path d attributes causes layout recalculation on every frame. Use transform (translate, scale, rotate) and opacity for smooth 60fps animations.
Not setting viewBox on SVG elements. Without viewBox, SVGs cannot scale proportionally. Always include viewBox and remove fixed width/height attributes (set dimensions via CSS or the parent element instead).
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeCreates, edits, reviews, and validates high-quality SVG graphics with W3C compliance, CSS independence, accessibility, and safety.
Generates and edits SVG logos, icons, and graphics. Covers path commands, shape primitives, styling, accessibility, gradients, masks, sprites, optimization, and animation techniques like CSS keyframes and SVG-specific methods.
Implements scalable icon systems with SVG sprites or React/Vue components. Use when setting up icon libraries, creating icon sizing tokens, optimizing SVGs, or building accessible icon buttons.