AgentSkillsCN

Performance

性能

SKILL.md

Performance Optimization Patterns

Best practices for application performance. Auto-discovered when performance work detected.

Core Principles

code
┌─────────────────────────────────────────────────────────────┐
│              PERFORMANCE GOLDEN RULES                       │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. Measure first, optimize second                          │
│  2. Optimize the critical path                              │
│  3. Cache expensive operations                              │
│  4. Minimize I/O operations                                 │
│  5. Load only what you need                                 │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Frontend Performance

1. Bundle Optimization

javascript
// Code splitting by route
const Dashboard = lazy(() => import('./Dashboard'));
const Settings = lazy(() => import('./Settings'));

// Named chunks for better caching
const Analytics = lazy(() =>
  import(/* webpackChunkName: "analytics" */ './Analytics')
);

// Tree shaking - import only what you need
// BAD
import _ from 'lodash';
_.map(arr, fn);

// GOOD
import { map } from 'lodash-es';
map(arr, fn);

2. Image Optimization

html
<!-- Responsive images -->
<picture>
  <source
    srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w"
    type="image/webp"
  />
  <img
    src="hero-800.jpg"
    alt="Hero"
    loading="lazy"
    decoding="async"
    width="800"
    height="600"
  />
</picture>

<!-- Modern formats with fallback -->
<picture>
  <source srcset="image.avif" type="image/avif" />
  <source srcset="image.webp" type="image/webp" />
  <img src="image.jpg" alt="..." />
</picture>

3. Rendering Performance

javascript
// Virtualization for long lists
import { FixedSizeList } from 'react-window';

const VirtualList = ({ items }) => (
  <FixedSizeList
    height={600}
    itemCount={items.length}
    itemSize={50}
    width="100%"
  >
    {({ index, style }) => (
      <div style={style}>{items[index].name}</div>
    )}
  </FixedSizeList>
);

// Memoization
const ExpensiveComponent = memo(({ data }) => {
  const processed = useMemo(
    () => heavyComputation(data),
    [data]
  );

  const handleClick = useCallback(
    () => onClick(data.id),
    [data.id, onClick]
  );

  return <div onClick={handleClick}>{processed}</div>;
});

// Debounce expensive operations
const debouncedSearch = useMemo(
  () => debounce(handleSearch, 300),
  [handleSearch]
);

4. Core Web Vitals

MetricTargetHow to Improve
LCP (Largest Contentful Paint)< 2.5sOptimize images, preload critical resources
FID (First Input Delay)< 100msBreak up long tasks, defer non-critical JS
CLS (Cumulative Layout Shift)< 0.1Set image dimensions, avoid inserting content above
javascript
// Measure Core Web Vitals
import { getLCP, getFID, getCLS } from 'web-vitals';

getLCP(console.log);
getFID(console.log);
getCLS(console.log);

Backend Performance

1. Database Optimization

python
# N+1 Query Problem
# BAD - N+1 queries
users = User.query.all()
for user in users:
    print(user.orders)  # Each access = new query!

# GOOD - Eager loading
users = User.query.options(joinedload(User.orders)).all()
for user in users:
    print(user.orders)  # No additional queries

# GOOD - Select only needed columns
users = User.query.with_entities(User.id, User.name).all()

# Pagination
users = User.query.paginate(page=1, per_page=20)

# Indexing
class User(db.Model):
    email = db.Column(db.String, index=True)  # Add index
    created_at = db.Column(db.DateTime, index=True)

# Composite index for common queries
__table_args__ = (
    db.Index('idx_user_status_date', 'status', 'created_at'),
)

2. Caching Strategies

python
# In-memory cache (Redis)
import redis
from functools import wraps

cache = redis.Redis()

def cached(ttl=300):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            key = f"{func.__name__}:{hash(str(args) + str(kwargs))}"

            # Try cache first
            result = cache.get(key)
            if result:
                return json.loads(result)

            # Compute and cache
            result = func(*args, **kwargs)
            cache.setex(key, ttl, json.dumps(result))
            return result
        return wrapper
    return decorator

@cached(ttl=60)
def get_user_stats(user_id):
    # Expensive computation
    return compute_stats(user_id)

# Cache invalidation
def update_user(user_id, data):
    db.update_user(user_id, data)
    cache.delete(f"get_user_stats:{hash(str((user_id,)))}")

3. Async Operations

python
# Async I/O
import asyncio
import aiohttp

async def fetch_all(urls):
    async with aiohttp.ClientSession() as session:
        tasks = [fetch_one(session, url) for url in urls]
        return await asyncio.gather(*tasks)

async def fetch_one(session, url):
    async with session.get(url) as response:
        return await response.json()

# Background tasks
from fastapi import BackgroundTasks

@app.post("/send-email")
async def send_email(
    email: str,
    background_tasks: BackgroundTasks
):
    background_tasks.add_task(send_email_task, email)
    return {"status": "queued"}

4. Connection Pooling

python
# Database connection pool
from sqlalchemy import create_engine

engine = create_engine(
    DATABASE_URL,
    pool_size=10,           # Maintain 10 connections
    max_overflow=20,        # Allow 20 more under load
    pool_timeout=30,        # Wait 30s for connection
    pool_recycle=1800,      # Recycle connections after 30m
)

# HTTP connection pool
import httpx

# Reuse client (don't create per request)
client = httpx.AsyncClient(
    limits=httpx.Limits(max_connections=100)
)

async def fetch(url):
    return await client.get(url)

API Performance

1. Response Optimization

python
# Pagination
@app.get("/items")
def get_items(page: int = 1, limit: int = 20):
    offset = (page - 1) * limit
    items = db.query(Item).offset(offset).limit(limit).all()
    total = db.query(Item).count()

    return {
        "data": items,
        "meta": {
            "page": page,
            "limit": limit,
            "total": total,
            "pages": ceil(total / limit)
        }
    }

# Field selection
@app.get("/users")
def get_users(fields: str = None):
    query = User.query

    if fields:
        columns = [getattr(User, f) for f in fields.split(",")]
        query = query.with_entities(*columns)

    return query.all()

# Compression
from fastapi.middleware.gzip import GZipMiddleware
app.add_middleware(GZipMiddleware, minimum_size=1000)

2. Caching Headers

python
from fastapi.responses import Response

@app.get("/static-data")
def get_static_data():
    return Response(
        content=json.dumps(data),
        headers={
            "Cache-Control": "public, max-age=3600",
            "ETag": compute_etag(data),
        }
    )

@app.get("/user-data")
def get_user_data():
    return Response(
        content=json.dumps(data),
        headers={
            "Cache-Control": "private, no-cache",
        }
    )

Performance Checklist

markdown
## Performance Review Checklist

### Frontend
- [ ] Bundle size analyzed (webpack-bundle-analyzer)
- [ ] Code splitting implemented
- [ ] Images optimized (WebP/AVIF, lazy loading)
- [ ] Core Web Vitals passing
- [ ] No layout shifts

### Backend
- [ ] Database queries optimized (no N+1)
- [ ] Proper indexes in place
- [ ] Caching implemented for hot paths
- [ ] Connection pooling configured
- [ ] Async where beneficial

### API
- [ ] Pagination on list endpoints
- [ ] Response compression enabled
- [ ] Proper cache headers
- [ ] Field selection available

### Monitoring
- [ ] Performance metrics tracked
- [ ] Alerts on degradation
- [ ] Slow query logging enabled

Measurement Tools

ToolPurpose
LighthouseFrontend audit
WebPageTestReal-world loading
Chrome DevToolsProfiling
EXPLAIN ANALYZESQL query analysis
py-spy / node --profBackend profiling
Prometheus + GrafanaMetrics & dashboards