optimize
Optimize code for performance, readability, or efficiency
What this skill does
# Performance Optimization Skill
Systematic approach to identifying and fixing performance issues.
## Name
han-core:optimize - Optimize code for performance, readability, or efficiency
## Synopsis
```
/optimize [arguments]
```
## Core Principle
**Measure, don't guess.** Optimization without data is guesswork.
## The Cardinal Rule
**NEVER optimize without measuring first**
**Why:** Premature optimization wastes time on non-issues while missing real problems.
**Exception:** Obvious O(n^2) algorithms when O(n) alternatives exist.
## Optimization Process
### 1. Measure Current State (Baseline)
**Before touching any code, establish metrics:**
**Frontend Performance:**
```bash
# Chrome DevTools Performance tab
# Lighthouse audit
npm run build && du -sh dist/ # Bundle size
```
**Backend Performance:**
```bash
# Add timing logs
start = Time.now
result = expensive_operation()
elapsed = Time.now - start
Logger.info("Operation took #{elapsed}ms")
```
**Database:**
```bash
# PostgreSQL
EXPLAIN ANALYZE SELECT ...;
# Check query time in logs
grep "SELECT" logs/production.log | grep "Duration:"
```
**Metrics to capture:**
- Load time / response time
- Time to interactive
- Bundle size
- Memory usage
- Query duration
- Render time
### 2. Profile to Find Bottlenecks
**Don't guess where the problem is - profile:**
**Browser Profiling:**
- Chrome DevTools > Performance tab
- Record interaction
- Look for long tasks (> 50ms)
- Check for layout thrashing
**Server Profiling:**
```bash
# Add detailed timing
defmodule Profiler do
def measure(label, func) do
start = System.monotonic_time(:millisecond)
result = func.()
elapsed = System.monotonic_time(:millisecond) - start
Logger.info("#{label}: #{elapsed}ms")
result
end
end
# Use it
Profiler.measure("Database query", fn ->
Repo.all(User)
end)
```
**React Profiling:**
```bash
# React DevTools Profiler
# Look for:
# - Unnecessary re-renders
# - Slow components (> 16ms for 60fps)
# - Large component trees
```
### 3. Identify Root Cause
**Common performance issues:**
**Frontend:**
- Large bundle size (lazy load, code split)
- Unnecessary re-renders (memoization)
- Blocking JavaScript (defer, async)
- Unoptimized images (WebP, lazy loading)
- Too many network requests (bundle, cache)
- Memory leaks (cleanup useEffect)
**Backend:**
- N+1 queries (preload associations)
- Missing database indexes
- Expensive computations in loops
- Synchronous external API calls
- Large JSON responses
- Inefficient algorithms
**Database:**
- Missing indexes
- Inefficient query structure
- Too many joins
- Fetching unnecessary columns
- No query result caching
### 4. Apply Targeted Optimization
**One change at a time** - Measure impact of each change
#### Frontend Optimizations
**Bundle Size Reduction:**
```typescript
// Before: Import entire library
import _ from 'lodash'
// After: Import only what's needed
import debounce from 'lodash/debounce'
// Or: Use native alternatives
const unique = [...new Set(array)] // Instead of _.uniq(array)
```
**React Performance:**
```typescript
// Before: Re-renders on every parent render
function ChildComponent({ items }) {
return <div>{items.map(...)}</div>
}
// After: Only re-render when items change
const ChildComponent = React.memo(function ChildComponent({ items }) {
return <div>{items.map(...)}</div>
}, (prev, next) => prev.items === next.items)
// Before: Recreates function every render
function Parent() {
const handleClick = () => { ... }
return <Child onClick={handleClick} />
}
// After: Stable function reference
function Parent() {
const handleClick = useCallback(() => { ... }, [])
return <Child onClick={handleClick} />
}
```
**Code Splitting:**
```typescript
// Before: All in main bundle
import HeavyComponent from './HeavyComponent'
// After: Lazy load when needed
const HeavyComponent = React.lazy(() => import('./HeavyComponent'))
function App() {
return (
<Suspense fallback={<Loading />}>
<HeavyComponent />
</Suspense>
)
}
```
**Image Optimization:**
```typescript
// Before: Full-size image
<img src="/hero.jpg" />
// After: Responsive, lazy-loaded
<img
src="/hero-800w.webp"
srcSet="/hero-400w.webp 400w, /hero-800w.webp 800w"
loading="lazy"
alt="Hero image"
/>
```
#### Backend Optimizations
**N+1 Query Fix:**
```elixir
# Before: N+1 queries (1 for users + N for posts)
users = Repo.all(User)
Enum.map(users, fn user ->
posts = Repo.all(from p in Post, where: p.user_id == ^user.id)
{user, posts}
end)
# After: 2 queries total
users = Repo.all(User) |> Repo.preload(:posts)
Enum.map(users, fn user -> {user, user.posts} end)
```
**Database Indexing:**
```sql
-- Before: Slow query
SELECT * FROM users WHERE email = '[email protected]';
-- Seq Scan (5000ms)
-- After: Add index
CREATE INDEX idx_users_email ON users(email);
-- Index Scan (2ms)
```
**Caching:**
```elixir
# Before: Expensive calculation every request
def get_popular_posts do
# Complex aggregation query (500ms)
Repo.all(from p in Post, ...)
end
# After: Cache for 5 minutes
def get_popular_posts do
Cachex.fetch(:app_cache, "popular_posts", fn ->
result = Repo.all(from p in Post, ...)
{:commit, result, ttl: :timer.minutes(5)}
end)
end
```
**Batch Processing:**
```elixir
# Before: Process one at a time
Enum.each(user_ids, fn id ->
user = Repo.get(User, id)
send_email(user)
end)
# After: Batch fetch
users = Repo.all(from u in User, where: u.id in ^user_ids)
Enum.each(users, &send_email/1)
```
#### Algorithm Optimization
**Reduce Complexity:**
```typescript
// Before: O(n^2) - nested loops
function findDuplicates(arr: number[]): number[] {
const duplicates = []
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j] && !duplicates.includes(arr[i])) {
duplicates.push(arr[i])
}
}
}
return duplicates
}
// After: O(n) - single pass with Set
function findDuplicates(arr: number[]): number[] {
const seen = new Set<number>()
const duplicates = new Set<number>()
for (const num of arr) {
if (seen.has(num)) {
duplicates.add(num)
}
seen.add(num)
}
return Array.from(duplicates)
}
```
### 5. Measure Impact (Proof of Work)
**ALWAYS measure after optimization:**
```markdown
## Optimization: [What was changed]
### Before
- Load time: 3.2s
- Bundle size: 850KB
- Time to interactive: 4.1s
### Changes
- Lazy loaded HeavyComponent
- Switched to lodash-es for tree shaking
- Added React.memo to ProductList
### After
- Load time: 1.8s (-44%)
- Bundle size: 520KB (-39%)
- Time to interactive: 2.3s (-44%)
### Evidence
```
```bash
# Before
$ npm run build
dist/main.js 850.2 KB
# After
$ npm run build
dist/main.js 520.8 KB
```
**Use proof-of-work skill to document evidence**
### 6. Verify Correctness
**Tests must still pass:**
```bash
# Run full test suite
npm test # Frontend
mix test # Backend
# Manual verification
# - Feature still works
# - Edge cases handled
# - No new bugs introduced
```
## Optimization Types
**Performance:**
- Algorithm complexity reduction
- Database query optimization
- Caching strategies
- Lazy loading and code splitting
**Code Quality:**
- Simplification and clarity
- Removing duplication
- Better naming and structure
- Pattern improvements
**Resource Efficiency:**
- Memory usage reduction
- Bundle size optimization
- Network request reduction
- Asset optimization
## Common Optimization Targets
### Frontend Checklist
- [ ] Bundle size < 200KB (gzipped)
- [ ] First Contentful Paint < 1.5s
- [ ] Time to Interactive < 3s
- [ ] No layout shift (CLS < 0.1)
- [ ] Images optimized (WebP, lazy loading)
- [ ] Code split by route
- [ ] Unused code removed (tree shaking)
- [ ] CSS critical path optimized
### Backend Checklist
- [ ] API response time < 200ms (p95)
- [ ] Database queries optimized (EXPLAIN ANALYZE)
- [ ] No N+1 queries
- [ ] AppropriatRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.