Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
One-time setup that gathers your project's design context and saves it to CLAUDE.md for future sessions.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
reference/optimize.md
1Performance is a feature. Identify the actual bottleneck for THIS interface, fix it, then measure. Don't optimize what isn't slow.23## Assess Performance Issues45Understand current performance and identify problems:671. **Measure current state**:8- **Core Web Vitals**: LCP, FID/INP, CLS scores9- **Load time**: Time to interactive, first contentful paint10- **Bundle size**: JavaScript, CSS, image sizes11- **Runtime performance**: Frame rate, memory usage, CPU usage12- **Network**: Request count, payload sizes, waterfall13142. **Identify bottlenecks**:15- What's slow? (Initial load? Interactions? Animations?)16- What's causing it? (Large images? Expensive JavaScript? Layout thrashing?)17- How bad is it? (Perceivable? Annoying? Blocking?)18- Who's affected? (All users? Mobile only? Slow connections?)1920**CRITICAL**: Measure before and after. Premature optimization wastes time. Optimize what actually matters.2122## Optimization Strategy2324Create systematic improvement plan:2526### Loading Performance2728**Optimize Images**:29- Use modern formats (WebP, AVIF)30- Proper sizing (don't load 3000px image for 300px display)31- Lazy loading for below-fold images32- Responsive images (`srcset`, `picture` element)33- Compress images (80-85% quality is usually imperceptible)34- Use CDN for faster delivery3536```html37<img38src="hero.webp"39srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w"40sizes="(max-width: 400px) 400px, (max-width: 800px) 800px, 1200px"41loading="lazy"42alt="Hero image"43/>44```4546**Reduce JavaScript Bundle**:47- Code splitting (route-based, component-based)48- Tree shaking (remove unused code)49- Remove unused dependencies50- Lazy load non-critical code51- Use dynamic imports for large components5253```javascript54// Lazy load heavy component55const HeavyChart = lazy(() => import('./HeavyChart'));56```5758**Optimize CSS**:59- Remove unused CSS60- Critical CSS inline, rest async61- Minimize CSS files62- Use CSS containment for independent regions6364**Optimize Fonts**:65- Use `font-display: swap` or `optional`66- Subset fonts (only characters you need)67- Preload critical fonts68- Use system fonts when appropriate69- Limit font weights loaded7071```css72@font-face {73font-family: 'CustomFont';74src: url('/fonts/custom.woff2') format('woff2');75font-display: swap; /* Show fallback immediately */76unicode-range: U+0020-007F; /* Basic Latin only */77}78```7980**Optimize Loading Strategy**:81- Critical resources first (async/defer non-critical)82- Preload critical assets83- Prefetch likely next pages84- Service worker for offline/caching85- HTTP/2 or HTTP/3 for multiplexing8687### Rendering Performance8889**Avoid Layout Thrashing**:90```javascript91// ❌ Bad: Alternating reads and writes (causes reflows)92elements.forEach(el => {93const height = el.offsetHeight; // Read (forces layout)94el.style.height = height * 2; // Write95});9697// ✅ Good: Batch reads, then batch writes98const heights = elements.map(el => el.offsetHeight); // All reads99elements.forEach((el, i) => {100el.style.height = heights[i] * 2; // All writes101});102```103104**Optimize Rendering**:105- Use CSS `contain` property for independent regions106- Minimize DOM depth (flatter is faster)107- Reduce DOM size (fewer elements)108- Use `content-visibility: auto` for long lists109- Virtual scrolling for very long lists (react-window, react-virtualized)110111**Reduce Paint & Composite**:112- Use `transform` and `opacity` for reliable movement, but allow blur, filters, masks, clip paths, shadows, and color shifts when they create meaningful polish113- Avoid casual animation of layout-driving properties (`width`, `height`, `top`, `left`, margins)114- Use `will-change` sparingly for known expensive operations115- Bound expensive paint areas for blur/filter/shadow effects (smaller and isolated is faster)116117### Animation Performance118119**GPU Acceleration**:120```css121/* ✅ GPU-accelerated (fast) */122.animated {123transform: translateX(100px);124opacity: 0.5;125}126127/* ❌ CPU-bound (slow) */128.animated {129left: 100px;130width: 300px;131}132```133134**Smooth 60fps**:135- Target 16ms per frame (60fps)136- Use `requestAnimationFrame` for JS animations137- Debounce/throttle scroll handlers138- Use CSS animations when possible139- Avoid long-running JavaScript during animations140141**Intersection Observer**:142```javascript143// Efficiently detect when elements enter viewport144const observer = new IntersectionObserver((entries) => {145entries.forEach(entry => {146if (entry.isIntersecting) {147// Element is visible, lazy load or animate148}149});150});151```152153### React/Framework Optimization154155**React-specific**:156- Use `memo()` for expensive components157- `useMemo()` and `useCallback()` for expensive computations158- Virtualize long lists159- Code split routes160- Avoid inline function creation in render161- Use React DevTools Profiler162163**Framework-agnostic**:164- Minimize re-renders165- Debounce expensive operations166- Memoize computed values167- Lazy load routes and components168169### Network Optimization170171**Reduce Requests**:172- Combine small files173- Use SVG sprites for icons174- Inline small critical assets175- Remove unused third-party scripts176177**Optimize APIs**:178- Use pagination (don't load everything)179- GraphQL to request only needed fields180- Response compression (gzip, brotli)181- HTTP caching headers182- CDN for static assets183184**Optimize for Slow Connections**:185- Adaptive loading based on connection (navigator.connection)186- Optimistic UI updates187- Request prioritization188- Progressive enhancement189190## Core Web Vitals Optimization191192### Largest Contentful Paint (LCP < 2.5s)193- Optimize hero images194- Inline critical CSS195- Preload key resources196- Use CDN197- Server-side rendering198199### First Input Delay (FID < 100ms) / INP (< 200ms)200- Break up long tasks201- Defer non-critical JavaScript202- Use web workers for heavy computation203- Reduce JavaScript execution time204205### Cumulative Layout Shift (CLS < 0.1)206- Set dimensions on images and videos207- Don't inject content above existing content208- Use `aspect-ratio` CSS property209- Reserve space for ads/embeds210- Avoid animations that cause layout shifts211212```css213/* Reserve space for image */214.image-container {215aspect-ratio: 16 / 9;216}217```218219## Performance Monitoring220221**Tools to use**:222- Chrome DevTools (Lighthouse, Performance panel)223- WebPageTest224- Core Web Vitals (Chrome UX Report)225- Bundle analyzers (webpack-bundle-analyzer)226- Performance monitoring (Sentry, DataDog, New Relic)227228**Key metrics**:229- LCP, FID/INP, CLS (Core Web Vitals)230- Time to Interactive (TTI)231- First Contentful Paint (FCP)232- Total Blocking Time (TBT)233- Bundle size234- Request count235236**IMPORTANT**: Measure on real devices with real network conditions. Desktop Chrome with fast connection isn't representative.237238**NEVER**:239- Optimize without measuring (premature optimization)240- Sacrifice accessibility for performance241- Break functionality while optimizing242- Use `will-change` everywhere (creates new layers, uses memory)243- Lazy load above-fold content244- Optimize micro-optimizations while ignoring major issues (optimize the biggest bottleneck first)245- Forget about mobile performance (often slower devices, slower connections)246247## Verify Improvements248249Test that optimizations worked:250251- **Before/after metrics**: Compare Lighthouse scores252- **Real user monitoring**: Track improvements for real users253- **Different devices**: Test on low-end Android, not just flagship iPhone254- **Slow connections**: Throttle to 3G, test experience255- **No regressions**: Ensure functionality still works256- **User perception**: Does it *feel* faster?257258When the user-facing numbers move, hand off to `$impeccable polish` for the final pass.259