Performance
Optimize generation, build, and runtime performance.
Generation Performance
Slow Code Generation
bash
# Generation takes minutes instead of secondsCause: Large OpenAPI spec or inefficient parsing
Solution:
bash
# 1. Split large specs into smaller files
# Instead of one 10MB file, use multiple smaller specs
# 2. Remove unused schemas
# Delete schemas not referenced by any endpoint
# 3. Use specific operations only
# Generate only what you need
nxh generate -i swagger.yaml -o ./composables --include getPet,createPet
# 4. Disable formatting during generation (if available)
nxh generate -i swagger.yaml -o ./composables --no-format
# Then format afterwards
prettier --write composables/**/*.tsMemory Usage During Generation
bash
JavaScript heap out of memory during generationCause: Very large OpenAPI spec
Solution:
bash
# Increase Node memory
export NODE_OPTIONS="--max-old-space-size=8192"
nxh generate -i swagger.yaml
# Or split spec into smaller parts
# Generate separately for different API sections
# Optimize OpenAPI spec
# - Remove duplicate schemas
# - Use $ref instead of inline schemas
# - Remove unused definitionsBuild Performance
Slow TypeScript Compilation
bash
# tsc takes minutes to compileCause: Too many files or complex types
Solution:
json
// tsconfig.json
{
"compilerOptions": {
"incremental": true, // ✅ Use incremental compilation
"skipLibCheck": true, // ✅ Skip checking node_modules
"isolatedModules": true // ✅ Faster parallel compilation
},
"exclude": [
"node_modules",
".nuxt",
".output"
]
}Large Bundle Size
bash
# .output/public/_nuxt/*.js files are hugeCause: Importing too much code
Solution:
typescript
// ❌ Bad - imports all composables
import * as api from '~/composables'
// ✅ Good - import only what you need
import { useFetchPet, useFetchOwner } from '~/composables/pets'
// nuxt.config.ts - enable code splitting
export default defineNuxtConfig({
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
composables: {
test: /composables/,
name: 'composables',
chunks: 'all'
}
}
}
}
})Slow Dev Server Startup
bash
# npm run dev takes long to startCause: Processing too many files
Solution:
typescript
// nuxt.config.ts
export default defineNuxtConfig({
// ✅ Disable features you don't need
typescript: {
typeCheck: false // Disable type checking in dev
},
// ✅ Exclude unnecessary directories
ignore: [
'docs/**',
'tests/**',
'**/*.test.ts'
],
// ✅ Use faster build tools
vite: {
optimizeDeps: {
include: ['h3', 'ofetch']
}
}
})Runtime Performance
Slow API Requests
typescript
// Requests take seconds instead of millisecondsCause: No caching or inefficient requests
Solution:
typescript
// ✅ Enable caching
const { data } = useFetchPets({
key: 'pets-list',
// Cached for 60 seconds
getCachedData(key) {
return useNuxtApp().payload.data[key]
}
})
// ✅ Use lazy loading when appropriate
const { data, pending, execute } = useFetchPet(petId, {
lazy: true,
immediate: false
})
// Only fetch when needed
onMounted(() => {
if (shouldFetch.value) {
execute()
}
})Too Many Parallel Requests
typescript
// Dozens of requests on page loadCause: Multiple composables fetching independently
Solution:
typescript
// ❌ Bad - 50 separate requests
pets.value.forEach(pet => {
useFetchPetDetails(pet.id)
})
// ✅ Good - batch request
const petIds = pets.value.map(p => p.id)
const { data: petDetails } = useFetchPetsBatch(petIds)
// Or use server endpoint to aggregate
// server/api/pets/batch.ts
export default defineEventHandler(async (event) => {
const { ids } = await readBody(event)
const pets = await Promise.all(
ids.map(id => getServerPet(event, id))
)
return pets
})Slow Server-Side Rendering
bash
# SSR takes seconds per pageCause: Slow API calls during SSR
Solution:
typescript
// ✅ Use caching for SSR
// server/api/pets.ts
import { defineCachedEventHandler } from '#nitro'
export default defineCachedEventHandler(
async (event) => {
return await getServerPets(event)
},
{
maxAge: 60 * 60, // ✅ Cache for 1 hour
swr: true, // ✅ Stale-while-revalidate
getKey: (event) => {
const query = getQuery(event)
return `pets-${query.page}-${query.limit}`
}
}
)
// ✅ Or use static generation for some pages
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/pets': { swr: 60 * 60 }, // ISR - cache 1 hour
'/pets/**': { swr: 60 * 60 }, // ISR for detail pages
'/about': { prerender: true } // Static generation
}
})Memory Leaks in SPA
bash
# Memory usage increases over timeCause: Not cleaning up composables
Solution:
typescript
// ✅ Always clean up
const { data, cancel } = useFetchPets()
onUnmounted(() => {
cancel() // ✅ Cancel pending requests
})
// ✅ Clear cache when needed
const clearPetsCache = () => {
const nuxtApp = useNuxtApp()
delete nuxtApp.payload.data['pets']
}
// ✅ Use weak references for large objects
const petCache = new WeakMap()Network Performance
Large Response Payloads
bash
# API returns 10MB JSON responseCause: Over-fetching data
Solution:
typescript
// ✅ Use pagination
const { data } = useFetchPets({
query: {
page: 1,
limit: 20 // ✅ Limit results
}
})
// ✅ Use field selection (if API supports)
const { data } = useFetchPet(1, {
query: {
fields: 'id,name,status' // ✅ Only get needed fields
}
})
// ✅ Use BFF to transform response
// server/api/pets/[id].ts
export default defineEventHandler(async (event) => {
const id = Number(event.context.params?.id)
const pet = await getServerPet(event, id)
// ✅ Return only what frontend needs
return {
id: pet.id,
name: pet.name,
status: pet.status
// Exclude large fields like images, full history, etc.
}
})No Request Compression
bash
# Responses not compressedCause: Backend not using compression
Solution:
typescript
// Enable compression on backend
// Express:
import compression from 'compression'
app.use(compression())
// Or use Cloudflare/CDN compression
// Check if enabled:
// Response Headers should have: content-encoding: gzipSlow DNS Resolution
bash
# DNS lookup takes secondsCause: Slow DNS server
Solution:
bash
# Use faster DNS
# Google DNS: 8.8.8.8
# Cloudflare: 1.1.1.1
# Or use IP directly (testing only)
NUXT_PUBLIC_API_BASE=http://192.168.1.100:8080
# Or add to /etc/hosts
echo "192.168.1.100 api.example.com" >> /etc/hostsType Performance
Slow TypeScript Intellisense
bash
# VSCode becomes slow with typesCause: Too many complex types
Solution:
typescript
// ✅ Simplify complex types
// Instead of deep intersections
type Pet = A & B & C & D & E & F
// Use interfaces
interface Pet extends A, B, C {
// Additional properties
}
// ✅ Use type aliases for complex unions
type PetStatus = 'available' | 'pending' | 'sold'
// Instead of repeating
status: 'available' | 'pending' | 'sold'Optimization Checklist
Generation Optimization
- [ ] Remove unused schemas from OpenAPI
- [ ] Use
$refinstead of inline schemas - [ ] Split large specs into smaller files
- [ ] Only generate needed operations
Build Optimization
- [ ] Enable
incrementalcompilation - [ ] Use
skipLibCheckin tsconfig - [ ] Enable code splitting
- [ ] Minimize bundle size
- [ ] Use tree shaking
Runtime Optimization
- [ ] Enable caching for repeated requests
- [ ] Use lazy loading where appropriate
- [ ] Batch parallel requests
- [ ] Implement pagination
- [ ] Use server-side caching
- [ ] Clean up on unmount
Network Optimization
- [ ] Use CDN for static assets
- [ ] Enable HTTP/2
- [ ] Use compression
- [ ] Minimize payload size
- [ ] Use field selection
Measuring Performance
Measure Generation Time
bash
time nxh generate -i swagger.yaml -o ./composablesMeasure Build Time
bash
time npm run buildAnalyze Bundle Size
bash
npm run build
npx nuxi analyze
# Or use webpack-bundle-analyzer
npm install --save-dev webpack-bundle-analyzerProfile Runtime Performance
typescript
// Use browser DevTools
// 1. Open DevTools (F12)
// 2. Go to Performance tab
// 3. Record while loading page
// 4. Analyze bottlenecks
// Or use Lighthouse
// 1. Open DevTools
// 2. Go to Lighthouse tab
// 3. Generate reportMonitor API Performance
typescript
// Add timing logs
const start = Date.now()
const { data } = await useFetchPet(1)
console.log(`Fetch took ${Date.now() - start}ms`)
// Or use global callback
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.provide('apiCallbacks', {
onRequest: (url) => {
const start = Date.now()
return { start }
},
onFinish: (context) => {
const duration = Date.now() - context.start
console.log(`${context.url} took ${duration}ms`)
}
})
})Caching Strategies
Browser Cache
typescript
// Use appropriate cache headers
// server/api/pets.ts
export default defineEventHandler(async (event) => {
const pets = await getServerPets(event)
// ✅ Cache in browser for 5 minutes
setResponseHeader(event, 'Cache-Control', 'public, max-age=300')
return pets
})Application Cache
typescript
// Use Nuxt payload cache
const { data } = useFetchPets({
key: 'pets',
getCachedData: (key) => {
return useNuxtApp().payload.data[key]
}
})
// Manual cache invalidation
const refreshPets = () => {
const nuxtApp = useNuxtApp()
delete nuxtApp.payload.data['pets']
refresh()
}Server Cache
typescript
// Use Nitro caching
import { defineCachedEventHandler } from '#nitro'
export default defineCachedEventHandler(
async (event) => {
return await getServerPets(event)
},
{
maxAge: 60,
swr: true
}
)