- Optimizing Performance
- When to Load
- Trigger
-
- Diagnosing slowness, profiling, caching strategies, reducing load times, bundle size optimization
- Skip
-
- Correctness-focused work where performance is not a concern
- Performance Optimization Workflow
- Copy this checklist and track progress:
- Performance Optimization Progress:
- - [ ] Step 1: Measure baseline performance
- - [ ] Step 2: Identify bottlenecks
- - [ ] Step 3: Apply targeted optimizations
- - [ ] Step 4: Measure again and compare
- - [ ] Step 5: Repeat if targets not met
- Critical Rule
- Never optimize without data. Always profile before and after changes. Step 1: Measure Baseline Profiling Commands
Node.js profiling
node --prof app.js node --prof-process isolate*.log
profile.txt
Python profiling
python -m cProfile -o profile.stats app.py python -m pstats profile.stats
Web performance
lighthouse https://example.com --output = json Step 2: Identify Bottlenecks Common Bottleneck Categories Category Symptoms Tools CPU High CPU usage, slow computation Profiler, flame graphs Memory High RAM, GC pauses, OOM Heap snapshots, memory profiler I/O Slow disk/network, waiting strace, network inspector Database Slow queries, lock contention Query analyzer, EXPLAIN Step 3: Apply Optimizations Frontend Optimizations Bundle Size: // ❌ Import entire library import _ from "lodash" ; // ✅ Import only needed functions import debounce from "lodash/debounce" ; // ✅ Use dynamic imports for code splitting const HeavyComponent = lazy ( ( ) => import ( "./HeavyComponent" ) ) ; Rendering: // ❌ Render on every parent update function Child ( { data } ) { return < ExpensiveComponent data = { data } /
; } // ✅ Memoize when props don't change const Child = memo ( function Child ( { data } ) { return < ExpensiveComponent data = { data } /
; } ) ; // ✅ Use useMemo for expensive computations const processed = useMemo ( ( ) => expensiveCalc ( data ) , [ data ] ) ; Images:
< img src = " large-image.jpg " />
<
img
src
=
"
image.webp
"
srcset
=
"
image-300.webp 300w, image-600.webp 600w
"
sizes
=
"
(max-width: 600px) 300px, 600px
"
loading
=
"
lazy
"
decoding
=
"
async
"
/>
Backend Optimizations
Database Queries:
-- ❌ N+1 Query Problem
SELECT
*
FROM
users
;
-- Then for each user:
SELECT
*
FROM
orders
WHERE
user_id
=
?
;
-- ✅ Single query with JOIN
SELECT
u
.
*
,
o
.
*
FROM
users u
LEFT
JOIN
orders o
ON
u
.
id
=
o
.
user_id
;
-- ✅ Or use pagination
SELECT
*
FROM
users
LIMIT
100
OFFSET
0
;
Caching Strategy:
// Multi-layer caching
const
getUser
=
async
(
id
)
=>
{
// L1: In-memory cache (fastest)
let
user
=
memoryCache
.
get
(
user:
${
id
}
)
;
if
(
user
)
return
user
;
// L2: Redis cache (fast)
user
=
await
redis
.
get
(
user:
${
id
}
)
;
if
(
user
)
{
memoryCache
.
set
(
user:
${
id
}
,
user
,
60
)
;
return
JSON
.
parse
(
user
)
;
}
// L3: Database (slow)
user
=
await
db
.
users
.
findById
(
id
)
;
await
redis
.
setex
(
user:
${
id
}
,
3600
,
JSON
.
stringify
(
user
)
)
;
memoryCache
.
set
(
user:
${
id
}
,
user
,
60
)
;
return
user
;
}
;
Async Processing:
// ❌ Blocking operation
app
.
post
(
"/upload"
,
async
(
req
,
res
)
=>
{
await
processVideo
(
req
.
file
)
;
// Takes 5 minutes
res
.
send
(
"Done"
)
;
}
)
;
// ✅ Queue for background processing
app
.
post
(
"/upload"
,
async
(
req
,
res
)
=>
{
const
jobId
=
await
queue
.
add
(
"processVideo"
,
{
file
:
req
.
file
}
)
;
res
.
send
(
{
jobId
,
status
:
"processing"
}
)
;
}
)
;
Algorithm Optimizations
// ❌ O(n²) - nested loops
function
findDuplicates
(
arr
)
{
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
.
push
(
arr
[
i
]
)
;
}
}
return
duplicates
;
}
// ✅ O(n) - hash map
function
findDuplicates
(
arr
)
{
const
seen
=
new
Set
(
)
;
const
duplicates
=
new
Set
(
)
;
for
(
const
item
of
arr
)
{
if
(
seen
.
has
(
item
)
)
duplicates
.
add
(
item
)
;
seen
.
add
(
item
)
;
}
return
[
...
duplicates
]
;
}
Step 4: Measure Again
After applying optimizations, re-run profiling and compare:
Comparison Checklist:
- [ ] Run same profiling tools as baseline
- [ ] Compare metrics before vs after
- [ ] Verify no regressions in other areas
- [ ] Document improvement percentages
Performance Targets
Web Vitals
Metric
Good
Needs Work
Poor
LCP
< 2.5s
2.5-4s
4s FID < 100ms 100-300ms 300ms CLS < 0.1 0.1-0.25 0.25 TTFB < 800ms 800ms-1.8s 1.8s API Performance Metric Target P50 Latency < 100ms P95 Latency < 500ms P99 Latency < 1s Error Rate < 0.1% Validation After optimization, validate results: Performance Validation: - [ ] Metrics improved from baseline - [ ] No functionality regressions - [ ] No new errors introduced - [ ] Changes are sustainable (not one-time fixes) - [ ] Performance gains documented If targets not met, return to Step 2 and identify remaining bottlenecks.