agentleFS
FirzusFirzus/agent-skills/skills/web/web-assets-optimization/SKILL.md

web-assets-optimization

Skill4 starsChanged 20 days agoMITView on GitHub

Audits and optimizes all web-app assets for performance: images (Sharp AVIF/WebP variants, responsive `img`/`picture`/`srcset`/`sizes`), video (ffmpeg H.264/VP9/AV1 encoding, posters, lazy loading), animated GIF replacement with video or animated WebP/AVIF, web fonts (WOFF2 subsetting, font-display, preload), and SVG (SVGO, sprites, currentColor). Builds a per-asset delivery strategy from importance, viewport placement, and LCP status (fetchpriority, lazy loading, preload, caching, CLS). Use when auditing asset weight, fixing LCP/CLS, compressing video, replacing GIFs, subsetting fonts, or adapting asset markup for Next.js, React, Vite, Astro, SvelteKit, or Nuxt.

The file

We split this skill into the rules it gives an agent

6 rules. About 0 are common, 2 are distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Do not add a package manager or root tooling to documentation-only repositories.

    line 40
  2. Distinctive:

    Never lazy-load an LCP candidate — including video posters and CSS background LCP images.

    line 41
  3. Very specific:

    Always reserve space: width/height (or CSS aspect-ratio) on every <img> AND <video>.

    line 42
  4. Very specific:

    Keep SVG logos/icons as vectors.

    line 46
  5. Very specific:

    Check package.json, framework configs, image/font component imports (next/image, next/font, astro:assets, @nuxt/image, @nuxt/fonts, …

    line 90
  6. Very specific:

    Run scan-assets.py. Review per type: path, bytes, dimensions (video dims are not detected — note as unknown), references, and usage hints …

    line 98

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Web Assets Optimization

Optimize the assets the app actually ships: images, video, animated media, fonts, and SVG. Prefer safe, measurable wins: smaller files, modern formats, responsive markup, stable layout, deliberate loading order, and framework-compatible delivery.

Leading words for this skill:

  • pipeline — extend the project's existing asset tooling; do not replace a working optimizer.
  • clean — write final asset paths only; leave no temp folders, task-created variants, or ffmpeg two-pass logs, and no orphaned heavy sources except those the user chose to keep.
  • strategy — every asset gets a deliberate decision from the matrix in Step 3 (importance x placement x loading context); no blanket policies.
  • LCP — treat LCP candidates (hero image, video poster, CSS background) as highest priority; never lazy-load them.

When not to use

  • The user wants generated artwork from prompts → use an image-generation skill.
  • The ask is a visual redesign with no asset-performance work.
  • Assets are already transformed by a CMS/CDN pipeline, unless the task is markup or config around that CDN.
  • Video editing/production work (cuts, color grading, subtitles) — this skill only compresses and delivers.
  • Sources are proprietary, or destructive edits are requested without backups.

Hard rules

  • Stay clean: optimized files land in kept public/assets paths; propose removing old unoptimized sources once unreferenced (Step 7); delete the variants, experimental output dirs, and ffmpeg -passlogfile logs this task created before finishing.
  • Optimize referenced assets first; unused archives only if the user asks.
  • Detect the framework before patching markup; prefer framework-native primitives already in use.
  • Do not add a package manager or root tooling to documentation-only repositories; in target apps, prefer existing package managers and scripts.
  • Never lazy-load an LCP candidate — including video posters and CSS background LCP images.
  • Always reserve space: width/height (or CSS aspect-ratio) on every <img> AND <video>.
  • Video: never ship AV1-only; always keep an MP4/H.264 fallback <source>; H.264 requires -pix_fmt yuv420p, even dimensions, and -movflags +faststart.
  • Animated GIFs used in pages: replace with <video> or animated WebP/AVIF unless the context only accepts image formats (README/Markdown renderers, email, Open Graph).
  • Fonts: ship WOFF2 only; font preloads always carry crossorigin, even same-origin.
  • Keep SVG logos/icons as vectors; when running SVGO, keep the viewBox (removeViewBox: false).
  • Preserve semantics: meaningful alt for content images, alt="" only when decorative; aria-label or nearby text for meaningful <video> (no alt exists).

Branches

AskPath
Audit onlySteps 1–3, then report (skip generation and markup).
Optimize + markupFull workflow below.
Single asset type (e.g. "compress this video", "fix our fonts", "replace these GIFs")Steps 1–3 scoped to that type, then the matching reference file and Steps 5–9 for those assets.
CDN/CMS already transformsStep 1 + markup/config only; see frameworks.md CMS section.
Delivery/LCP tuning only (no re-encoding)Steps 1–3 + Step 6 with delivery-strategy.md.

Workflow

Track with this checklist (one item per step below):

- [ ] 1. Detect framework and asset pipeline
- [ ] 2. Inventory referenced assets (images, video, GIFs, fonts, SVG)
- [ ] 3. Build the per-asset strategy matrix
- [ ] 4. Plan per-type transforms and commands
- [ ] 5. Generate optimized assets into final paths
- [ ] 6. Replace references with optimized markup and loading attributes
- [ ] 7. Delete the old unoptimized assets and unused variants the user approves
- [ ] 8. Re-scan and verify references stay clean
- [ ] 9. Verify visuals/build and report

Scripts

Resolve this skill's directory (the folder that contains this SKILL.md), then run helpers relative to that root. Pass --root as the target app path.

python3 <skill-dir>/scripts/scan-assets.py --root <app-root> --format markdown
python3 <skill-dir>/scripts/scan-assets.py --root <app-root> --format json > asset-scan.json
python3 <skill-dir>/scripts/generate-sharp-plan.py asset-scan.json --widths 320,640,1024,1536
python3 <skill-dir>/scripts/generate-ffmpeg-plan.py asset-scan.json

Inside this repository only, <skill-dir> is skills/web/web-assets-optimization.

Step 1 — Detect framework and pipeline

Check package.json, framework configs, image/font component imports (next/image, next/font, astro:assets, @nuxt/image, @nuxt/fonts, @sveltejs/enhanced-img), and CDN/CMS loaders. If a working pipeline exists, extend it.

Done when: the framework (or plain HTML) plus any existing optimizers for images AND fonts are named, and the patch strategy is chosen (native component vs plain markup).

See frameworks.md.

Step 2 — Inventory referenced assets

Run scan-assets.py. Review per type: path, bytes, dimensions (video dims are not detected — note as unknown), references, and usage hints (logo, app-icon, favicon, animated, poster, preload, legacy-font-format).

Done when: every referenced local image/video/GIF/font/SVG under --root is listed; large unreferenced assets are noted; remote URLs are listed separately.

Step 3 — Build the strategy matrix

This is the intelligence step — do not skip it. For each asset that matters (raster > 200 KB, any video, any GIF > 100 KB, every shipped font file, SVG > 20 KB, plus every LCP candidate regardless of size), record one strategy row: asset | type | role | placement | action | loading policy.

  • Role: LCP candidate / contentful / decorative / functional (icon, favicon).
  • Placement: above fold / below fold / offscreen-conditional (modal, carousel, tab) / global (font, sprite).
  • LCP candidates include: <img>, <video> poster, CSS background-image via url(), <image> in <svg>.

Loading policy per role x placement:

Role x placementLoading policy
LCP candidateeager, fetchpriority="high", never lazy; must be discoverable in initial HTML; preload only if late-discovered (CSS background, font)
Above-fold, non-LCPeager, default priority, dimensions set
Below-fold image/iframeloading="lazy", decoding="async", dimensions mandatory
Offscreen-conditional (modal, carousel, tab)loading="lazy" (or defer the fetch until the trigger interaction for modal/tab content); fetchpriority="low" on prefetched carousel slides so they do not compete with critical resources
Below-fold autoplay video looppreload="none" + poster, or IntersectionObserver src-swap; pause offscreen
Click-to-play videopreload="metadata" (or none) + poster
Long offscreen sectionscontent-visibility: auto + contain-intrinsic-size
Critical text fontWOFF2 subset, preload with crossorigin, font-display: swap/fallback + metric-adjusted fallback
Secondary/decorative fontfont-display: optional, no preload
Animated GIF in pagereplace per animated-media.md, reduced-motion fallback

Order of work: LCP candidate → oversized above-fold assets → video/GIF byte hogs → fonts → below-fold rasters → SEO/social images. Details and rationale: delivery-strategy.md.

Done when: every qualifying asset has a matrix row and the LCP candidate is identified (or its absence stated).

Step 4 — Plan per-type transforms

Dispatch per type; read the reference file before planning that type:

  • Raster images → sharp-cli.md + generate-sharp-plan.py. Default format policy unless the project constrains otherwise: photos AVIF + WebP + JPEG fallback; UI screenshots WebP + PNG when lossless detail matters; transparent rasters WebP/AVIF with PNG fallback; logos/icons stay SVG; Open Graph/social images JPEG/PNG at platform dimensions.
  • Video → video.md + generate-ffmpeg-plan.py (MP4 + WebM + poster).
  • GIF/animated → animated-media.md + generate-ffmpeg-plan.py.
  • Fonts → fonts.md (WOFF2 conversion, subsetting, display strategy).
  • SVG → svg.md (SVGO plan, delivery method).

Done when: each matrix row has planned commands or a stated no-op reason.

Step 5 — Generate into final paths

Review the generated command plans, then run them. Target final kept paths (avoid --out-dir unless you will move winners into final paths and delete the temp dir before finishing). Produce only variants the app will reference; delete ffmpeg pass logs.

Done when: optimized files exist at final paths for every planned row and no temp output or log remains.

Step 6 — Replace references

Apply the matrix's loading policy while patching markup. Before editing image markup, load responsive-images.md and apply every Core rule; for video/GIF markup follow video.md and animated-media.md; for @font-face/preload edits follow fonts.md; for priorities/preload/caching follow delivery-strategy.md.

Also update manifests, favicons, Open Graph, CSS url(...), MDX/Markdown, and structured data when they point at old files. Prefer framework-native patterns when the pipeline uses them.

Done when: no runtime reference still points at an unoptimized original that has a replacement, and every touched element carries the loading attributes its matrix row prescribes (or exceptions are documented).

Step 7 — Delete old assets

List unreferenced heavy originals (rasters, videos, GIFs, legacy font formats) and unused variants that predate this task, and delete them once the user approves that list. Remove the temp output directories this task created. Keep SVG sources and any source files the user asked to retain.

Done when: the tree is clean — only referenced optimized assets, intentional vectors, and documented kept sources remain, including originals the user chose to keep.

Step 8 — Re-scan and verify cleanliness

Rerun scan-assets.py. Confirm optimized references are in place, no orphaned heavy assets remain, and no legacy font formats are still shipped.

Done when: the rescan matches the clean bar above.

Step 9 — Verify and report

Check desktop/mobile render, sensible srcset picks, video plays with correct source order and poster, autoplay loops are muted + playsinline, fonts render without layout jumps, no CLS from missing dimensions, LCP not lazy-loaded, and the build passes with the project's existing commands. Compare bytes before/after per type.

Done when: validation notes are recorded and the report below is filled.

Output format

## Web assets optimization summary

- Framework/pipeline detected: <framework and asset tooling>
- Assets scanned: <count> (<images/videos/GIFs/fonts/SVG counts>); bytes before → after: <totals>
- LCP candidate: <asset and treatment>
- Highest-priority fixes: <short list>

## Strategy matrix

| Asset | Type | Role | Placement | Action | Loading policy |
| --- | --- | --- | --- | --- | --- |
| ... | ... | ... | ... | ... | ... |

## Changes made

- <source asset> → <optimized replacements in final paths>
- <reference file> → <old path replaced with optimized markup>
- Deleted: <old assets, temp folders, unused variants, pass logs>

## Validation

- <commands or manual checks>
- Scanner rerun: <clean confirmation or documented exceptions>

## Notes / follow-ups

- <remote assets, CMS/CDN settings, caching headers, visual QA needs>

Reference files

  • delivery-strategy.md — LCP, fetchpriority, lazy loading, preload/preconnect, content-visibility, CLS, caching, measurement.
  • responsive-images.md — img, picture, srcset, sizes, LCP images, accessibility, SEO.
  • video.md — codecs, ffmpeg recipes, posters, <video> markup, lazy patterns, streaming decision.
  • animated-media.md — GIF replacement with video or animated WebP/AVIF, reduced motion.
  • fonts.md — WOFF2, subsetting, font-display, preload, fallback metrics, variable fonts.
  • svg.md — SVGO, delivery trade-offs, currentColor.
  • sharp-cli.md — Sharp CLI commands, quality table, naming, conversion policy.
  • frameworks.md — Next.js, React/Vite, Astro, SvelteKit, Nuxt asset/font/video handling, CDN constraints.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.