| name | performance |
| description | Performance optimization for web applications. Use when optimizing frontend rendering, backend response times, database queries, or system resources. |
Performance Skill
Performance optimization techniques for frontend, backend, and database layers.
When to Use This Skill
- Optimizing page load times
- Reducing API response latency
- Improving database query performance
- Memory and CPU optimization
- Caching strategies
⚡ Frontend Performance
Core Web Vitals
| Metric | Target | Description |
|---|
| LCP | < 2.5s | Largest Contentful Paint |
| FID | < 100ms | First Input Delay |
| CLS | < 0.1 | Cumulative Layout Shift |
Bundle Optimization
const Dashboard = lazy(() => import('./pages/Dashboard'));
const routes = [
{
path: '/dashboard',
component: lazy(() => import('./pages/Dashboard')),
},
];
Image Optimization
import Image from 'next/image';
<Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={600}
priority // Above the fold
placeholder="blur"
/>
<Image
src="/feature.jpg"
loading="lazy"
/>
React Optimization
const sortedData = useMemo(() => {
return data.sort((a, b) => a.name.localeCompare(b.name));
}, [data]);
const handleClick = useCallback((id: string) => {
setSelected(id);
}, []);
const ExpensiveList = memo(({ items }) => (
<ul>
{items.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
));
import { FixedSizeList } from 'react-window';
<FixedSizeList
height={400}
itemCount={10000}
itemSize={35}
>
{({ index, style }) => (
<div style={style}>{items[index].name}</div>
)}
</FixedSizeList>
CSS Performance
div.container ul li a span { }
.nav-link-text { }
.animated-element {
will-change: transform;
}
.card {
contain: layout paint;
}
🚀 Backend Performance
Go Optimization
Reduce Allocations
for i := 0; i < 1000; i++ {
result = append(result, processItem(i))
}
result := make([]Item, 0, 1000)
for i := 0; i < 1000; i++ {
result = append(result, processItem(i))
}
Use sync.Pool
var bufferPool = sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
}
func processRequest(data []byte) {
buf := bufferPool.Get().(*bytes.Buffer)
defer func() {
buf.Reset()
bufferPool.Put(buf)
}()
buf.Write(data)
}
Efficient JSON Handling
json.NewEncoder(w).Encode(data)
import "github.com/bytedance/sonic"
sonic.Marshal(data)
Goroutine Patterns
func processItems(items []Item, workers int) []Result {
jobs := make(chan Item, len(items))
results := make(chan Result, len(items))
for w := 0; w < workers; w++ {
go func() {
for item := range jobs {
results <- process(item)
}
}()
}
for _, item := range items {
jobs <- item
}
close(jobs)
output := make([]Result, len(items))
for i := range output {
output[i] = <-results
}
return output
}
💾 Caching Strategies
Cache Patterns
┌─────────────┐ miss ┌─────────────┐
│ Client │ ────────── │ Database │
└─────────────┘ └─────────────┘
│ │
│ hit │
▼ │
┌─────────────┐ │
│ Cache │ ◄─────────────────┘
└─────────────┘ populate
Redis Caching
import "github.com/redis/go-redis/v9"
type CacheService struct {
client *redis.Client
ttl time.Duration
}
func (c *CacheService) Get(ctx context.Context, key string, dest interface{}) error {
val, err := c.client.Get(ctx, key).Result()
if err == redis.Nil {
return ErrCacheMiss
}
if err != nil {
return err
}
return json.Unmarshal([]byte(val), dest)
}
func (c *CacheService) Set(ctx context.Context, key string, value interface{}) error {
data, err := json.Marshal(value)
if err != nil {
return err
}
return c.client.Set(ctx, key, data, c.ttl).Err()
}
func (s *Service) GetUser(ctx context.Context, id string) (*User, error) {
cacheKey := "user:" + id
var user User
if err := s.cache.Get(ctx, cacheKey, &user); err == nil {
return &user, nil
}
user, err := s.db.GetUser(ctx, id)
if err != nil {
return nil, err
}
s.cache.Set(ctx, cacheKey, user)
return user, nil
}
Cache Invalidation
func (s *Service) UpdateUser(ctx context.Context, user *User) error {
if err := s.db.UpdateUser(ctx, user); err != nil {
return err
}
cacheKey := "user:" + user.ID
s.cache.Delete(ctx, cacheKey)
return nil
}
func (s *Service) InvalidateUserCaches(ctx context.Context, userID string) {
keys := []string{
"user:" + userID,
"user:profile:" + userID,
"user:settings:" + userID,
}
s.cache.Delete(ctx, keys...)
}
🗃️ Database Performance
Query Optimization
EXPLAIN ANALYZE
SELECT u.*, COUNT(o.id) as order_count
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE u.created_at > '2024-01-01'
GROUP BY u.id;
CREATE INDEX idx_users_created_at ON users(created_at);
CREATE INDEX idx_orders_user_id ON orders(user_id);
Connection Pooling
db, err := sql.Open("postgres", connString)
if err != nil {
return err
}
db.SetMaxOpenConns(25)
db.SetMaxIdleConns(5)
db.SetConnMaxLifetime(5 * time.Minute)
db.SetConnMaxIdleTime(1 * time.Minute)
N+1 Query Prevention
users := db.GetAllUsers()
for _, user := range users {
orders := db.GetOrdersByUser(user.ID)
}
users := db.Preload("Orders").Find(&users)
userIDs := extractIDs(users)
ordersByUser := db.GetOrdersForUsers(userIDs)
📊 Monitoring & Profiling
Go Profiling
import _ "net/http/pprof"
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
go tool pprof http://localhost:6060/debug/pprof/heap
go tool pprof -http=:8080 cpu.prof
Request Tracing
func TimingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
wrapped := &responseWriter{ResponseWriter: w}
next.ServeHTTP(wrapped, r)
duration := time.Since(start)
logger.Info("request",
zap.String("method", r.Method),
zap.String("path", r.URL.Path),
zap.Int("status", wrapped.status),
zap.Duration("duration", duration),
)
if duration > 2*time.Second {
logger.Warn("slow request", zap.Duration("duration", duration))
}
})
}
📚 References