From harness-claude
Optimizes CSS performance using content-visibility, containment, efficient selectors, and Core Web Vitals patterns for long pages, CLS issues, large bundles, and animation jank.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Optimize CSS performance with content-visibility, containment, efficient selectors, and Core Web Vitals-friendly patterns
Optimizes Tailwind CSS for production builds using JIT mode, precise content paths, safelist for dynamic classes, and best practices to minimize bundle size and boost performance.
Optimizes Tailwind CSS performance covering v4 Rust engine improvements, JIT compilation, content detection, tree shaking, dynamic class name solutions, and transition best practices for faster builds and smaller bundles.
Optimizes Tailwind CSS v4 code for performance with best practices on build config, CSS generation, bundle size, theming, utilities, responsive design, and container queries. Use when writing, reviewing, or refactoring v4 code.
Share bugs, ideas, or general feedback.
Optimize CSS performance with content-visibility, containment, efficient selectors, and Core Web Vitals-friendly patterns
content-visibility: auto on off-screen sections to skip rendering until they scroll into view.width and height or aspect-ratio to prevent CLS.will-change sparingly and only on elements about to animate — it allocates GPU memory.transform and opacity animations over properties that trigger layout (see animation skill).content paths precisely to avoid scanning unnecessary files.font-display: swap for web fonts to prevent invisible text during font loading.// content-visibility for long lists
function ProductList({ products }: { products: Product[] }) {
return (
<div>
{products.map((product) => (
<div
key={product.id}
className="contain-layout-style"
style={{
contentVisibility: 'auto',
containIntrinsicSize: '0 200px', // Estimated height
}}
>
<ProductCard product={product} />
</div>
))}
</div>
);
}
// Prevent CLS with aspect ratio
function ResponsiveImage({ src, alt }: { src: string; alt: string }) {
return (
<div className="relative aspect-video w-full overflow-hidden rounded-lg bg-gray-100">
<img
src={src}
alt={alt}
className="absolute inset-0 h-full w-full object-cover"
loading="lazy"
decoding="async"
width={1280}
height={720}
/>
</div>
);
}
// Skeleton loader that matches final layout
function CardSkeleton() {
return (
<div className="rounded-lg border p-6 space-y-4">
<div className="h-6 w-3/4 bg-gray-200 rounded animate-pulse" />
<div className="h-4 w-full bg-gray-200 rounded animate-pulse" />
<div className="h-4 w-5/6 bg-gray-200 rounded animate-pulse" />
<div className="h-10 w-32 bg-gray-200 rounded animate-pulse" />
</div>
);
}
/* Font loading optimization */
@font-face {
font-family: 'Inter';
font-display: swap; /* Show fallback immediately, swap when loaded */
src: url('/fonts/inter.woff2') format('woff2');
font-weight: 100 900;
}
content-visibility: auto: The browser skips rendering for off-screen elements. On pages with 500+ elements, this can reduce initial render time by 50% or more. The containIntrinsicSize hint prevents layout shifts when elements come into view.
CSS containment (contain property):
layout — element's layout does not affect siblingspaint — element's content does not render outside its boundsstyle — counters and quotes are scopedcontent — shorthand for layout paint stylestrict — shorthand for layout paint style sizeTailwind utilities: contain-none, contain-content, contain-strict, contain-layout, contain-paint.
Tailwind bundle optimization:
content configuration: ['./src/app/**/*.tsx', './src/components/**/*.tsx']node_modules in content paths (massive scan, no utility matches)safelist only for truly dynamic classes (from API data)Core Web Vitals impact:
| Metric | CSS Impact | Solution |
|---|---|---|
| LCP | Large CSS blocks render | Critical CSS inlining, font-display: swap |
| CLS | Dynamic size changes | aspect-ratio, explicit dimensions |
| INP | Layout thrashing from animations | transform/opacity only, containment |
will-change anti-pattern:
/* Bad — permanently allocates GPU memory for all cards */
.card {
will-change: transform;
}
/* Good — only when animation is imminent */
.card:hover {
will-change: transform;
}
.card.animating {
will-change: transform, opacity;
}
Lazy loading images:
// Native lazy loading
<img loading="lazy" decoding="async" src="..." />;
// Next.js Image component handles this automatically
import Image from 'next/image';
<Image src="..." width={800} height={400} alt="..." />;
CSS performance debugging: Use Chrome DevTools > Performance panel to identify:
https://web.dev/articles/content-visibility