Added AI skills
This commit is contained in:
139
.agents/skills/zod/references/perf-avoid-dynamic-creation.md
Normal file
139
.agents/skills/zod/references/perf-avoid-dynamic-creation.md
Normal file
@@ -0,0 +1,139 @@
|
||||
---
|
||||
title: Avoid Dynamic Schema Creation in Hot Paths
|
||||
impact: LOW-MEDIUM
|
||||
impactDescription: Zod 4's JIT compilation makes schema creation slower; creating schemas in loops adds ~0.15ms per creation
|
||||
tags: perf, dynamic, hot-path, optimization
|
||||
---
|
||||
|
||||
## Avoid Dynamic Schema Creation in Hot Paths
|
||||
|
||||
Zod 4 uses JIT (Just-In-Time) compilation to speed up repeated parsing, but this makes initial schema creation slower. Avoid creating schemas inside loops or frequently-called functions—pre-create them instead.
|
||||
|
||||
**Incorrect (schema creation in hot path):**
|
||||
|
||||
```typescript
|
||||
import { z } from 'zod'
|
||||
|
||||
async function validateBatch(items: unknown[]) {
|
||||
const results = []
|
||||
|
||||
for (const item of items) {
|
||||
// Schema created for EACH item - slow!
|
||||
const schema = z.object({
|
||||
id: z.string(),
|
||||
value: z.number(),
|
||||
})
|
||||
|
||||
results.push(schema.safeParse(item))
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
// 1000 items = 1000 schema creations = ~150ms overhead
|
||||
```
|
||||
|
||||
**Correct (pre-created schema):**
|
||||
|
||||
```typescript
|
||||
import { z } from 'zod'
|
||||
|
||||
// Schema created ONCE
|
||||
const itemSchema = z.object({
|
||||
id: z.string(),
|
||||
value: z.number(),
|
||||
})
|
||||
|
||||
async function validateBatch(items: unknown[]) {
|
||||
// Reuse the same schema instance
|
||||
return items.map(item => itemSchema.safeParse(item))
|
||||
}
|
||||
|
||||
// 1000 items = 1 schema creation + 1000 fast parses
|
||||
```
|
||||
|
||||
**Dynamic schemas with caching:**
|
||||
|
||||
```typescript
|
||||
import { z } from 'zod'
|
||||
|
||||
// Cache for dynamically-configured schemas
|
||||
const schemaCache = new WeakMap<object, z.ZodType>()
|
||||
|
||||
function getSchemaForConfig(config: { fields: string[] }) {
|
||||
// Check cache first
|
||||
if (schemaCache.has(config)) {
|
||||
return schemaCache.get(config)!
|
||||
}
|
||||
|
||||
// Create and cache
|
||||
const shape: Record<string, z.ZodString> = {}
|
||||
for (const field of config.fields) {
|
||||
shape[field] = z.string()
|
||||
}
|
||||
|
||||
const schema = z.object(shape)
|
||||
schemaCache.set(config, schema)
|
||||
return schema
|
||||
}
|
||||
|
||||
// Subsequent calls with same config reuse cached schema
|
||||
```
|
||||
|
||||
**Lazy schema creation:**
|
||||
|
||||
```typescript
|
||||
import { z } from 'zod'
|
||||
|
||||
// Schema created only when first used
|
||||
let _userSchema: z.ZodObject<any> | null = null
|
||||
|
||||
function getUserSchema() {
|
||||
if (!_userSchema) {
|
||||
_userSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
email: z.string().email(),
|
||||
profile: z.object({
|
||||
name: z.string(),
|
||||
avatar: z.string().url().optional(),
|
||||
}),
|
||||
})
|
||||
}
|
||||
return _userSchema
|
||||
}
|
||||
|
||||
// Or use a getter
|
||||
const schemas = {
|
||||
_user: null as z.ZodType | null,
|
||||
get user() {
|
||||
if (!this._user) {
|
||||
this._user = z.object({ /* ... */ })
|
||||
}
|
||||
return this._user
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Benchmark considerations:**
|
||||
|
||||
```typescript
|
||||
// Zod 4 JIT compilation:
|
||||
// - Schema creation: ~0.15ms per schema
|
||||
// - First parse: triggers JIT compile
|
||||
// - Subsequent parses: 7-14x faster
|
||||
|
||||
// For schemas used once:
|
||||
// - Creation + parse: ~0.15ms + first-parse overhead
|
||||
// - Consider if validation is even needed
|
||||
|
||||
// For schemas used many times:
|
||||
// - Create once, parse many: optimal
|
||||
// - JIT compilation amortized over all parses
|
||||
```
|
||||
|
||||
**When NOT to use this pattern:**
|
||||
- One-off validation where schema is used once
|
||||
- Dynamically generated forms where fields change per request
|
||||
- Test files where performance doesn't matter
|
||||
|
||||
Reference: [Zod v4 Performance](https://zod.dev/v4#performance)
|
||||
Reference in New Issue
Block a user