feat(hub-guide): expand plugin with 26 best-practice skills, hooks, and references
Transform hub-guide from a single-skill Hub monorepo guide into a comprehensive programming best-practice plugin covering all situations. Skills (26): - Core: engineering-principles, clean-code, clean-architecture, design-patterns, testing, error-handling, security, api-design, git-workflow, documentation, logging-observability, performance - Languages: typescript, python, rust, go - Frameworks: react-frontend, elysiajs, hono-backend, drizzle-database, nextjs - Infrastructure: docker, ci-cd, monitoring - Monorepo: monorepo, hub-guide (existing) Hooks: - SessionStart: auto-detect project type and activate relevant skills - PreToolUse (Write|Edit): inject language-specific rules per file type Reference files for deep dives: - clean-architecture/references/solid.md (SOLID + component principles) - design-patterns/references/catalog.md (full GoF catalog with examples) - testing/references/mocks.md (test double taxonomy) Restructure plugin to modern skills/ directory format.
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
---
|
||||
name: performance
|
||||
description: Best practices for software performance — caching, query optimization, lazy loading, profiling, CDN, database indexing, and memory management. Use when optimizing slow endpoints, reducing load times, designing caching strategies, or whenever the user mentions "performance," "optimization," "slow," "cache," "lazy loading," "profiling," "bottleneck," "N+1," "latency," "throughput," or "scalability."
|
||||
---
|
||||
|
||||
# Performance Best Practices
|
||||
|
||||
## Core Principle
|
||||
|
||||
**Measure before optimizing.** A guess is wrong more than half the time. Profile first, then fix the real bottleneck.
|
||||
|
||||
## Frontend Performance
|
||||
|
||||
### Loading
|
||||
- **Lazy load** — images, components, routes, heavy modules. Only what's needed now.
|
||||
- **Code splitting** — split by route (dynamic imports), not by random chunks.
|
||||
- **Preload critical assets** — `<link rel="preload">` for fonts, hero images, critical CSS.
|
||||
- **Prefetch likely navigations** — `<link rel="prefetch">` for pages user is likely to visit.
|
||||
|
||||
### Rendering
|
||||
- **Virtual lists** — for 100+ items. windowing (react-window, tanstack-virtual).
|
||||
- **Debounce/throttle** — search inputs (300ms debounce), scroll handlers (throttle 100ms).
|
||||
- **Avoid layout thrashing** — batch DOM reads/writes. Use `requestAnimationFrame`.
|
||||
- **CSS containment** — `contain: contents` isolates sub-trees from layout recalc.
|
||||
|
||||
### Assets
|
||||
- **Images** — next-gen formats (WebP, AVIF), responsive (`srcset`), lazy loading (`loading="lazy"`).
|
||||
- **Fonts** — `font-display: swap`, subset fonts, preload critical ones.
|
||||
- **Bundles** — tree-shaking enabled, minification, compression (brotli > gzip).
|
||||
|
||||
## Backend Performance
|
||||
|
||||
### Database
|
||||
|
||||
| Issue | Fix |
|
||||
|-------|-----|
|
||||
| **N+1 queries** | Eager loading (`.with()`, `.include()`, `JOIN`) |
|
||||
| **Missing index** | `EXPLAIN ANALYZE` to find sequential scans. Add indexes on `WHERE`/`JOIN`/`ORDER BY` columns |
|
||||
| **Too many rows** | Pagination, cursor-based, limit queries |
|
||||
| **Expensive joins** | Denormalize, materialized view, or caching layer |
|
||||
| **Large JSON fields** | Only select columns needed, not `SELECT *` |
|
||||
|
||||
```sql
|
||||
-- ❌ N+1
|
||||
for each order: SELECT * FROM items WHERE order_id = ?
|
||||
-- ✅ Eager load
|
||||
SELECT * FROM items WHERE order_id IN (?, ?, ?, ...)
|
||||
```
|
||||
|
||||
### Caching Strategy
|
||||
|
||||
```
|
||||
Request → CDN (static assets) → API Gateway → App Cache → DB
|
||||
```
|
||||
|
||||
| Layer | Cache | TTL | Invalidates |
|
||||
|-------|-------|-----|-------------|
|
||||
| **CDN** | Static assets, API responses | Long (1yr for assets) | Version hash |
|
||||
| **HTTP** | `Cache-Control`, ETag | Varies | `If-None-Match` |
|
||||
| **App** | Redis, in-memory | Seconds-minutes | Write-through / TTL |
|
||||
| **DB** | Query cache, connection pool | Intrinsic | Row changes |
|
||||
|
||||
**Cache patterns:**
|
||||
```typescript
|
||||
// Cache-aside (most common)
|
||||
async function getUser(id: string): Promise<User> {
|
||||
const cached = await cache.get(`user:${id}`);
|
||||
if (cached) return JSON.parse(cached);
|
||||
const user = await db.select().from(users).where(eq(users.id, id));
|
||||
await cache.set(`user:${id}`, JSON.stringify(user), 'EX', 300); // 5 min TTL
|
||||
return user;
|
||||
}
|
||||
```
|
||||
|
||||
### Connection Pooling
|
||||
- **Database:** pool of 10-50 connections (not 1, not unlimited).
|
||||
- **HTTP:** keep-alive, connection reuse. H2 multiplexing.
|
||||
- **Redis:** single connection reused, not new connection per request.
|
||||
|
||||
## Network Performance
|
||||
|
||||
- **Compression** — brotli for static, gzip as fallback. Enable in Traefik (`compress` middleware).
|
||||
- **HTTP/2** — multiplexing, header compression, server push. Enabled by default in Traefik.
|
||||
- **CDN** — CloudFlare, Fastly, CloudFront for static assets and API edge caching.
|
||||
- **Keep-alive** — reuse TCP connections. Default Timeout 60s.
|
||||
- **Latency budget** — 200ms total is good for most apps. Track per service.
|
||||
|
||||
## Profiling
|
||||
|
||||
### When you think something is slow:
|
||||
1. **Define the measurement** — what's slow? p50? p99? cold start?
|
||||
2. **Profile** — flame graphs (pyroscope, pprof), APM (Jaeger spans).
|
||||
3. **Find the bottleneck** — is it CPU? IO? Network? Database? Memory?
|
||||
4. **Fix one thing** — measure again. If no improvement, revert and try next.
|
||||
|
||||
### Tools by Language
|
||||
|
||||
| Language | Profiling | Flame Graphs |
|
||||
|----------|-----------|--------------|
|
||||
| TypeScript | Chrome DevTools, Node `--prof` | `0x` tool |
|
||||
| Rust | `perf`, `flamegraph`, `pprof-rs` | `cargo flamegraph` |
|
||||
| Go | `pprof` (runtime built-in) | `go tool pprof -http` |
|
||||
| Python | `cProfile`, `py-spy` | `flameprof` |
|
||||
|
||||
## Performance Budgets
|
||||
|
||||
Set measurable limits and enforce them:
|
||||
- **Lighthouse** — 90+ Performance score
|
||||
- **Bundle size** — <200KB JS (compressed), <50KB CSS
|
||||
- **LCP** (Largest Contentful Paint) — <2.5s
|
||||
- **FID** (First Input Delay) — <100ms
|
||||
- **CLS** (Cumulative Layout Shift) — <0.1
|
||||
- **API p99** — <500ms
|
||||
- **First byte** — <200ms
|
||||
|
||||
## Anti-patterns
|
||||
|
||||
- ❌ **Premature optimization** — optimizing before measuring. "Make it work, make it right, make it fast."
|
||||
- ❌ **Caching everything** — cache invalidation is hard. Cache what's expensive and stable.
|
||||
- ❌ **Over-indexing** — too many indexes slow writes. Index what's queried, not every column.
|
||||
- ❌ **SELECT *** — fetches columns you don't need. Increases memory and network.
|
||||
- ❌ **Sync over async** — blocking calls in async context (Node event loop blocking).
|
||||
- ❌ **Fat dependencies** — importing a 50KB library for one function. Prefer tree-shakeable modules.
|
||||
Reference in New Issue
Block a user