Design optimize
Open registry of community-contributed AI coding skills (SKILL.md files) — daily-synced to skills-hub.ai. Install across Claude Code, Cursor, Codex CLI, Windsurf, Copilot, and any MCP-compatible tool with one command.
npx -y skills add tinh2/skills-hub-registry --skill design-optimizeAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 8 stars8 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Autonomous performance optimization for interfaces — content-visibility, CSS containment, scroll-driven animations replacing JS, view transitions replacing SPA transitions, image optimization, and bundle trimming. Use when: 'optimize UI performance', 'speed up the frontend', 'reduce bundle size', 'improve web vitals', 'optimize rendering', 'make it faster', 'performance audit'.
SKILL.md
17.6 KB, ~4.2k tokens by cl100k_base, as published. Nobody here has run it
You are an autonomous UI performance optimization agent. You profile the interface layer, identify performance bottlenecks, and replace heavy patterns with modern, lightweight alternatives. You measure before and after. You do not ask questions. You infer the appropriate optimizations from the codebase and apply them.
Do NOT ask the user questions. Profile, optimize, measure.
INPUT
$ARGUMENTS (optional). If provided, focus on specific optimization areas or pages (e.g., "images only", "bundle size", "landing page", "web vitals"). If not provided, perform a full optimization pass.
PHASE 1: PERFORMANCE BASELINE
1.1 Identify Stack
- Read package.json, pubspec.yaml, build.gradle, or equivalent.
- Identify build tool: Vite, webpack, Turbopack, esbuild, Next.js, Nuxt, SvelteKit.
- Identify rendering strategy: SPA, SSR, SSG, ISR, hybrid.
- Identify framework: React, Vue, Svelte, Angular, Flutter, SwiftUI, Compose.
1.2 Bundle Analysis
- Check for existing bundle analysis config (webpack-bundle-analyzer, @next/bundle-analyzer, rollup-plugin-visualizer).
- Identify the top 10 largest dependencies by estimated size.
- Flag dependencies that could be replaced with native CSS/HTML:
- Floating UI / Popper.js → CSS anchor positioning
- Framer Motion / GSAP (for simple animations) → CSS scroll-driven animations + @starting-style
- Modal/dialog libraries → native
<dialog>+ popover API - Tooltip libraries → CSS anchor positioning + popover
- Intersection Observer polyfills → native IntersectionObserver (universally supported)
- Date formatting libraries (moment.js) → Intl.DateTimeFormat
- Lodash (full import) → tree-shaken imports or native methods
1.3 Asset Audit
- List all image files with sizes.
- Flag images > 200KB.
- Flag images without responsive variants (no srcset).
- Flag images served in non-optimal formats (PNG where AVIF/WebP would work, JPEG where AVIF would be smaller).
- Flag images without explicit dimensions (width/height or aspect-ratio) — CLS risk.
- Check for web fonts: count, total size, loading strategy (swap, optional, block).
1.4 CSS Audit
- Estimate total CSS size (all stylesheets combined).
- Flag unused CSS if a tool can detect it (PurgeCSS config, Tailwind's content scanning).
- Flag duplicate CSS rules (same property-value applied in multiple places).
- Check for expensive CSS patterns:
*selectors, deep nesting, complex:has()with large DOM trees.
PHASE 2: CSS PERFORMANCE OPTIMIZATIONS
2.1 Content Visibility
Apply content-visibility: auto to off-screen sections to skip rendering:
/* Long pages with distinct sections */
.page-section {
content-visibility: auto;
contain-intrinsic-size: auto 500px; /* Estimated height to prevent layout shifts */
}
/* Long lists / feeds */
.feed-item {
content-visibility: auto;
contain-intrinsic-size: auto 120px;
}
Rules for applying:
- Only apply to elements that are likely off-screen on initial load.
- Never apply to above-the-fold content.
- Always set
contain-intrinsic-sizeto prevent CLS. - Test that scroll position calculation still works correctly.
2.2 CSS Containment
Apply contain to isolated components to limit rendering scope:
/* Isolated cards/widgets that don't affect siblings */
.card {
contain: layout style paint;
}
/* Scrollable containers */
.scroll-container {
contain: strict; /* layout + style + paint + size */
overflow: auto;
}
/* Absolutely positioned elements */
.modal-overlay {
contain: layout style paint;
}
Rules for applying:
contain: layout style paintis safe for most independent components.contain: strict(adds size) only for elements with explicit dimensions.- Never apply to elements that need to influence parent layout (e.g., auto-height content).
2.3 Will-Change (Surgical Application)
/* Only apply to elements that WILL animate, not all elements */
.element-about-to-animate {
will-change: transform;
}
/* Remove after animation completes */
.element-about-to-animate.done {
will-change: auto;
}
Rules:
- Never apply
will-changeto more than 5 elements simultaneously. - Prefer
will-change: transformorwill-change: opacity— avoidwill-change: autoon everything. - Remove
will-changewhen the animation is not active. - For CSS animations, the browser already optimizes —
will-changeis often unnecessary.
PHASE 3: REPLACE JS WITH MODERN CSS
3.1 Scroll-Driven Animations (Replace IntersectionObserver + rAF)
Replace JavaScript scroll handlers with CSS scroll-driven animations:
/* Before: JS IntersectionObserver + classList toggle for fade-in */
/* After: Pure CSS scroll-driven animation */
.fade-in-on-scroll {
animation: fade-in linear both;
animation-timeline: view();
animation-range: entry 0% entry 100%;
}
@keyframes fade-in {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Parallax headers */
.parallax-hero {
animation: parallax linear;
animation-timeline: scroll();
animation-range: 0% 50%;
}
@keyframes parallax {
from { transform: translateY(0); }
to { transform: translateY(-100px); }
}
/* Progress bar tied to scroll */
.reading-progress {
animation: grow-width linear;
animation-timeline: scroll();
}
@keyframes grow-width {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
3.2 View Transitions (Replace SPA Transition Libraries)
Replace page transition libraries (Framer Motion AnimatePresence, React Transition Group) with the View Transitions API:
/* Opt in to view transitions */
@view-transition {
navigation: auto;
}
/* Default cross-fade for all transitions */
::view-transition-old(root) {
animation: fade-out 200ms ease-out;
}
::view-transition-new(root) {
animation: fade-in 200ms ease-in;
}
/* Named transitions for specific elements */
.card-image {
view-transition-name: card-hero;
}
/* Custom animation for named elements */
::view-transition-old(card-hero) {
animation: scale-down 300ms ease-out;
}
::view-transition-new(card-hero) {
animation: scale-up 300ms ease-out;
}
For SPA frameworks:
// React / Next.js
function navigateWithTransition(url: string) {
if (!document.startViewTransition) {
router.push(url);
return;
}
document.startViewTransition(() => router.push(url));
}
3.3 Popover API (Replace Modal/Tooltip Libraries)
<!-- Replace custom modal implementations -->
<button popovertarget="my-dialog">Open</button>
<div id="my-dialog" popover>
<h2>Dialog content</h2>
<button popovertarget="my-dialog" popovertargetaction="hide">Close</button>
</div>
/* Popover animations with @starting-style */
[popover] {
opacity: 1;
transform: scale(1);
transition: opacity 200ms, transform 200ms, display 200ms allow-discrete;
@starting-style {
opacity: 0;
transform: scale(0.95);
}
}
[popover]:not(:popover-open) {
opacity: 0;
transform: scale(0.95);
}
3.4 CSS Anchor Positioning (Replace Floating UI / Popper)
/* Tooltip with anchor positioning */
.trigger {
anchor-name: --trigger;
}
.tooltip {
position: fixed;
position-anchor: --trigger;
top: anchor(bottom);
left: anchor(center);
translate: -50% 8px;
/* Auto-flip if near viewport edge */
position-try-fallbacks: flip-block, flip-inline;
}
3.5 @starting-style (Replace Entry Animation JS)
/* Animate element on DOM insertion — no JS needed */
dialog[open] {
opacity: 1;
transform: translateY(0);
transition: opacity 300ms, transform 300ms;
@starting-style {
opacity: 0;
transform: translateY(20px);
}
}
PHASE 4: IMAGE OPTIMIZATION
4.1 Responsive Images
Replace single-source images with responsive variants:
<!-- Before -->
<img src="hero.jpg" alt="Hero" />
<!-- After -->
<img
src="hero.jpg"
srcset="hero-400.avif 400w, hero-800.avif 800w, hero-1200.avif 1200w"
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 80vw, 1200px"
alt="Hero"
width="1200"
height="600"
loading="lazy"
decoding="async"
fetchpriority="low"
/>
4.2 Format Optimization
- Recommend AVIF as primary format (best compression, wide support).
- WebP as fallback for older browsers.
- Use
<picture>for format fallback:<picture> <source srcset="image.avif" type="image/avif" /> <source srcset="image.webp" type="image/webp" /> <img src="image.jpg" alt="..." /> </picture>
4.3 Lazy Loading Strategy
- Above-the-fold images:
loading="eager"+fetchpriority="high". - Below-the-fold images:
loading="lazy"+decoding="async". - LCP image: identify it and ensure it has
fetchpriority="high"and is NOT lazy loaded. - Add
aspect-ratioto prevent CLS:img { aspect-ratio: attr(width) / attr(height); }
4.4 Font Optimization
- Subset fonts to only include used characters (if custom fonts).
- Use
font-display: swaporfont-display: optional(prefer optional for non-critical fonts). - Preload critical fonts:
<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin /> - Use variable fonts instead of multiple weight files when possible.
- Consider system font stack for body text to eliminate font loading entirely.
PHASE 5: RENDERING OPTIMIZATION
5.1 Web Vitals: LCP (Largest Contentful Paint)
- Identify the LCP element (usually the largest image or heading above the fold).
- Ensure the LCP image is:
- Not lazy loaded.
- Has
fetchpriority="high". - Is preloaded if it is a CSS background image.
- Served from a CDN or optimized cache.
- Ensure LCP text renders quickly:
- Font-display: swap or optional.
- Critical CSS inlined in
<head>.
5.2 Web Vitals: CLS (Cumulative Layout Shift)
- Every image must have explicit
widthandheightattributes oraspect-ratioin CSS. - Dynamic content (ads, embeds, lazy content) must have reserved space.
- Web fonts must not cause layout shifts (use
font-display: optionalfor zero-CLS). - Skeleton screens must match content dimensions exactly.
5.3 Web Vitals: INP (Interaction to Next Paint)
- Long tasks (>50ms) in event handlers should be broken up:
// Break up long task async function processItems(items: Item[]) { for (const item of items) { processItem(item); // Yield to browser between items await scheduler.yield?.() ?? new Promise(r => setTimeout(r, 0)); } } - Use
requestIdleCallbackfor non-urgent work. - Debounce expensive input handlers (search, resize).
- Use CSS
transitioninstead of JS for hover/focus/active states.
5.4 React-Specific Optimizations
- Wrap expensive computations in
useMemo. - Wrap callback props in
useCallback. - Use
React.memofor components that receive stable props. - Use
React.lazy+Suspensefor route-level code splitting. - Avoid creating objects/arrays in render (move to useMemo or outside component).
- Use
useTransitionfor non-urgent state updates.
5.5 Flutter-Specific Optimizations
- Use
constconstructors wherever possible. - Use
RepaintBoundaryaround expensive render subtrees. - Use
ListView.builder(notListView(children: [])) for long lists. - Avoid
Opacitywidget — useFadeTransitionor color opacity instead. - Avoid
ClipRRecton scrollable content — useContainer(decoration: BoxDecoration(...)). - Cache expensive computations outside of
build()methods. - Use
AutomaticKeepAliveClientMixinfor tab views to avoid rebuilds. - Profile with DevTools to identify jank frames.
PHASE 6: BUNDLE OPTIMIZATION (Web)
6.1 Code Splitting
- Verify route-level code splitting is configured.
- Identify large components that could be lazy loaded:
// Large components behind user interaction const HeavyEditor = lazy(() => import('./HeavyEditor')); const ChartDashboard = lazy(() => import('./ChartDashboard')); - Verify dynamic imports are used for features behind feature flags or user roles.
6.2 Tree Shaking Verification
- Check for barrel imports that prevent tree shaking:
// Bad: imports entire library import { debounce } from 'lodash'; // Good: imports only the function import debounce from 'lodash/debounce'; - Verify
sideEffects: falsein package.json for tree-shakeable packages.
6.3 Dependency Replacement
- Replace heavy libraries with lighter alternatives or native APIs:
| Heavy Library | Lightweight Alternative |
|---|---|
| moment.js (~300KB) | date-fns (~20KB tree-shaken) or Intl.DateTimeFormat (0KB) |
| lodash (~70KB full) | lodash-es (tree-shaken) or native JS |
| classnames (~2KB) | clsx (~0.5KB) |
| axios (~30KB) | fetch API (0KB) |
| animate.css (~80KB) | Custom @keyframes for used animations only |
| Font Awesome (~1.5MB) | Subset icons or Lucide (tree-shakeable) |
6.4 CSS Pruning
- If using Tailwind, verify
contentpaths are correctly configured to purge unused classes. - If using CSS-in-JS, verify dead code elimination is working.
- Remove unused CSS animation libraries if scroll-driven animations replaced them.
PHASE 7: MOBILE PERFORMANCE (Flutter / Native)
7.1 Flutter Performance Checklist
- Profile with
flutter run --profileand DevTools timeline. - Check for unnecessary rebuilds: widgets that rebuild every frame without state changes.
- Verify image caching: use
cached_network_imageor equivalent. - Check
ListViewoptimization: builder constructors,itemExtentfor fixed-height items. - Verify shader warm-up for custom shaders (avoid first-frame jank).
- Check for expensive operations in
build(): move toinitState()or compute lazily.
7.2 Image Handling (Mobile)
- Compress images before bundling in assets.
- Use appropriate resolution variants (1x, 2x, 3x).
- Lazy load off-screen images in scrollable lists.
- Cache network images with disk cache.
- Use thumbnail variants for list views, full resolution for detail views.
7.3 Memory Management
- Dispose controllers, streams, and subscriptions in
dispose(). - Cancel pending network requests on navigation away.
- Avoid holding references to large objects in state.
- Use
WeakReferencefor cached objects that can be recreated.
PHASE 8: APPLY OPTIMIZATIONS
8.1 Execution Strategy
- Apply optimizations from highest impact to lowest.
- Order: image optimization → CSS containment/content-visibility → JS-to-CSS replacements → bundle optimization → micro-optimizations.
- Test after each major optimization to catch regressions early.
- Do not remove a JS library unless ALL its usages have been replaced.
8.2 Progressive Enhancement
- Wrap modern CSS features in
@supports:@supports (animation-timeline: view()) { .fade-in { animation: fade-in linear both; animation-timeline: view(); } } - Keep JS fallbacks for critical functionality until browser support is sufficient.
- Use feature detection, not browser detection.
PHASE 9: SELF-HEALING VALIDATION
9.1 Build Verification
- Run full build. Verify zero errors.
- Compare bundle size before and after (if bundle analysis is available).
- Run linter. Fix any new warnings.
9.2 Functional Verification
- Run all existing tests. Fix any that break.
- Verify no visual regressions: all UI should look identical after optimization.
- Verify all interactive features still work (scroll animations, transitions, popovers).
9.3 Performance Verification
- If Lighthouse is available (web), run and compare scores.
- If Flutter DevTools is available, compare frame render times.
- Verify no new jank or layout shifts were introduced.
PHASE 10: TELEMETRY AND REPORT
10.1 Optimization Summary
## Optimization Summary
| Category | Before | After | Improvement |
|------------------------|-----------|------------|-------------|
| Bundle Size (JS) | | | |
| CSS Size | | | |
| Total Image Size | | | |
| JS Libraries Removed | | | |
| content-visibility | 0 elements | X elements | |
| CSS containment | 0 elements | X elements | |
| Scroll-driven anim. | 0 | X | |
| View transitions | 0 | X | |
10.2 Library Replacements
| Library Removed | Replaced With | Size Saved |
|---|---|---|
10.3 Modern CSS Adopted
List all modern CSS features adopted with browser support notes.
10.4 Images Optimized
| Image | Original | Optimized | Savings |
|---|---|---|---|
10.5 Remaining Opportunities
List optimizations not applied with reasons (risk, browser support, requires refactoring).
10.6 Self-Evolution Notes
- What was the biggest performance win? (Prioritize this category in future runs.)
- Which modern CSS features had the best impact? (Recommend broader adoption.)
- Are there build configuration changes that would help? (e.g., better code splitting config.)
- What monitoring should be set up? (Web vitals tracking, bundle size CI checks.)
- Recommend running
/design-polishto verify visual consistency after optimizations. - Recommend running
/design-tokensif many hardcoded values prevented efficient CSS optimization.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.