TypeScript Performance Optimization Systematic performance optimization for JavaScript/TypeScript codebases. Combines audit workflow with expert-level optimization patterns for runtime performance. NEVER Do When Optimizing Performance Note: For general best practices (type safety with / , avoiding , not mutating parameters), use the skill instead. This section focuses exclusively on performance-specific anti-patterns. - NEVER assume code is cold path - Utility functions, formatters, parsers, and validators appear simple but are frequently called in loops, rendering pipelines, or real-time sys…

, email)) {\n validEmails.push(email);\n }\n}\n```\n\n**✅ Correct: curry to compile regex once**\n```ts\nfunction validate(pattern: string): (value: string) => boolean;\nfunction validate(pattern: string, value: string): boolean;\nfunction validate(\n pattern: string,\n value?: string,\n): boolean | ((value: string) => boolean) {\n const regex = new RegExp(pattern);\n\n if (value === undefined) {\n return (v: string) => regex.test(v);\n }\n\n return regex.test(value);\n}\n\nconst isValidEmail = validate('^[a-z]+@[a-z]+\\\\.[a-z]+

TypeScript Performance Optimization Systematic performance optimization for JavaScript/TypeScript codebases. Combines audit workflow with expert-level optimization patterns for runtime performance. NEVER Do When Optimizing Performance Note: For general best practices (type safety with / , avoiding , not mutating parameters), use the skill instead. This section focuses exclusively on performance-specific anti-patterns. - NEVER assume code is cold path - Utility functions, formatters, parsers, and validators appear simple but are frequently called in loops, rendering pipelines, or real-time sys…

);\nfor (const email of emails) {\n if (isValidEmail(email)) {\n validEmails.push(email);\n }\n}\n```\n\n### Currying for Configuration\n\n**❌ Incorrect: pass same config repeatedly**\n```ts\nfunction formatCurrency(config: FormatConfig, amount: number): string {\n const symbol = config.currencySymbol;\n const decimals = config.decimalPlaces;\n const multiplier = 10 ** decimals;\n\n return symbol + (Math.round(amount * multiplier) / multiplier).toFixed(decimals);\n}\n\n// Called thousands of times with same config\nfor (const transaction of transactions) {\n display(formatCurrency(usdConfig, transaction.amount));\n}\n```\n\n**✅ Correct: curry to capture config**\n```ts\nfunction formatCurrency(config: FormatConfig): (amount: number) => string;\nfunction formatCurrency(config: FormatConfig, amount: number): string;\nfunction formatCurrency(\n config: FormatConfig,\n amount?: number,\n): string | ((amount: number) => string) {\n const symbol = config.currencySymbol;\n const decimals = config.decimalPlaces;\n const multiplier = 10 ** decimals;\n\n const format = (amt: number) =>\n symbol + (Math.round(amt * multiplier) / multiplier).toFixed(decimals);\n\n if (amount === undefined) {\n return format;\n }\n\n return format(amount);\n}\n\nconst formatUSD = formatCurrency(usdConfig);\nfor (const transaction of transactions) {\n display(formatUSD(transaction.amount));\n}\n```\n\n### Partial Application with bind\n\n**❌ Incorrect: repeated identical calls**\n```ts\nfunction scale(factor: number, base: number, value: number): number {\n return base + value * factor;\n}\n\nfor (const measurement of measurements) {\n scaled.push(scale(2.5, 100, measurement));\n}\n```\n\n**✅ Correct: use bind for partial application**\n```ts\nfunction scale(factor: number, base: number, value: number): number {\n return base + value * factor;\n}\n\nconst scaleMeasurement = scale.bind(null, 2.5, 100);\nfor (const measurement of measurements) {\n scaled.push(scaleMeasurement(measurement));\n}\n```\n\n**Note**: `bind()` has overhead. For hot paths, prefer explicit currying as shown in previous examples.\n\n### Currying for Validation Rules\n\n**❌ Incorrect: recreate validators**\n```ts\nfunction validateRange(min: number, max: number, value: number): boolean {\n return value >= min && value \u003c= max;\n}\n\nfor (const score of scores) {\n if (!validateRange(0, 100, score)) {\n errors.push(`Invalid score: ${score}`);\n }\n}\n```\n\n**✅ Correct: curry to create reusable validator**\n```ts\nfunction validateRange(min: number, max: number): (value: number) => boolean;\nfunction validateRange(min: number, max: number, value: number): boolean;\nfunction validateRange(\n min: number,\n max: number,\n value?: number,\n): boolean | ((value: number) => boolean) {\n const check = (v: number) => v >= min && v \u003c= max;\n\n if (value === undefined) {\n return check;\n }\n\n return check(value);\n}\n\nconst isValidScore = validateRange(0, 100);\nfor (const score of scores) {\n if (!isValidScore(score)) {\n errors.push(`Invalid score: ${score}`);\n }\n}\n```\n\n### When NOT to Curry\n\n**✅ Good: parameters vary frequently**\n```ts\nfunction add(a: number, b: number): number {\n return a + b;\n}\n\n// Both parameters change every call\nfor (let i = 0; i \u003c items.length; i++) {\n totals[i] = add(items[i].price, items[i].tax);\n}\n```\n\nDon't curry when:\n- Parameters vary on every call\n- Function is called infrequently\n- Setup cost is negligible\n- Currying adds more overhead than it saves\n\n### Currying with TypeScript Generics\n\n**❌ Incorrect: lose type information**\n```ts\nfunction map\u003cT, U>(fn: (item: T) => U, items: T[]): U[] {\n return items.map(fn);\n}\n\n// Have to pass fn and items together\nconst doubled = map((x: number) => x * 2, [1, 2, 3]);\n```\n\n**✅ Correct: curry with generics**\n```ts\nfunction map\u003cT, U>(fn: (item: T) => U): (items: T[]) => U[];\nfunction map\u003cT, U>(fn: (item: T) => U, items: T[]): U[];\nfunction map\u003cT, U>(\n fn: (item: T) => U,\n items?: T[],\n): U[] | ((items: T[]) => U[]) {\n const mapper = (arr: T[]) => arr.map(fn);\n\n if (items === undefined) {\n return mapper;\n }\n\n return mapper(items);\n}\n\n// Create reusable mapper\nconst double = map((x: number) => x * 2);\nconst doubled1 = double([1, 2, 3]);\nconst doubled2 = double([4, 5, 6]);\n```\n\n## Guidelines\n\n- **Profile first**: Measure to confirm the parameter is expensive to compute\n- **Constant parameters**: Curry when some parameters are constant across many calls\n- **Hot paths**: Prioritize currying in loops, event handlers, and frequently-called functions\n- **Expensive setup**: Curry functions with expensive validation, computation, or object creation\n- **TypeScript**: Use function overloads to support both curried and direct-call APIs\n- **Closure cost**: Be aware curried functions capture variables in closure (minimal overhead)\n\n## When to Use Currying\n\nCurry functions when:\n- Parameters include expensive computations (exponentiation, regex, lookup tables)\n- Some parameters are constant across hundreds/thousands of calls\n- Function is in a hot path (loop, render, event handler)\n- Setup/validation cost is significant\n- Creating specialized versions improves API ergonomics\n\n## When NOT to Use Currying\n\nAvoid currying when:\n- All parameters vary on every call\n- Function is called infrequently\n- Setup cost is trivial (simple primitives)\n- Currying complexity outweighs performance gain\n- Premature optimization in cold paths\n\n## Fallback Patterns\n\nWhen currying doesn't work, use these alternatives:\n\n### Fallback 1: Direct function calls when parameters vary\n\n**Scenario**: All parameters change on every call\n```ts\n// ❌ Don't curry - no benefit\nconst add = (a: number) => (b: number) => a + b;\n\nfor (let i = 0; i \u003c items.length; i++) {\n totals[i] = add(items[i].price)(items[i].tax); // Awkward and slow\n}\n```\n\n**✅ Use direct function call**\n```ts\nfunction add(a: number, b: number): number {\n return a + b;\n}\n\nfor (let i = 0; i \u003c items.length; i++) {\n totals[i] = add(items[i].price, items[i].tax); // Clear and fast\n}\n```\n\n**Why**: Currying adds closure overhead (function creation, variable capture) with zero benefit when all parameters vary.\n\n### Fallback 2: Inline computation when setup cost is trivial\n\n**Scenario**: Operation is so simple that currying adds complexity\n```ts\n// ❌ Over-engineered\nconst multiply = (factor: number) => (value: number) => factor * value;\nconst double = multiply(2);\n\nfor (const x of values) {\n results.push(double(x));\n}\n```\n\n**✅ Inline the trivial operation**\n```ts\nfor (const x of values) {\n results.push(x * 2); // No abstraction needed\n}\n```\n\n**Why**: For trivial operations (multiplication, addition), the overhead of function calls exceeds any benefit. Inline when the operation is simpler than the abstraction.\n\n### Fallback 3: Memoization for expensive pure functions\n\n**Scenario**: Function is expensive but parameters vary frequently\n```ts\n// ❌ Currying doesn't help - parameters vary\nfunction fibonacci(n: number): number {\n if (n \u003c= 1) return n;\n return fibonacci(n - 1) + fibonacci(n - 2);\n}\n\n// Called with different values each time\nfor (const num of numbers) {\n results.push(fibonacci(num)); // O(2^n) each call\n}\n```\n\n**✅ Use memoization instead**\n```ts\nconst fibCache = new Map\u003cnumber, number>();\n\nfunction fibonacci(n: number): number {\n if (n \u003c= 1) return n;\n if (fibCache.has(n)) return fibCache.get(n)!;\n\n const result = fibonacci(n - 1) + fibonacci(n - 2);\n fibCache.set(n, result);\n return result;\n}\n\nfor (const num of numbers) {\n results.push(fibonacci(num)); // O(n) total with cache\n}\n```\n\n**Why**: When parameters vary but repeat, memoization is more effective than currying. Cache stores results by input rather than precomputing constants.\n\n### Fallback 4: Loop hoisting for simple invariants\n\n**Scenario**: Simple invariant doesn't need currying\n```ts\n// ❌ Overkill for simple hoisting\nconst addTax = (rate: number) => (amount: number) => amount * (1 + rate);\nconst withTax = addTax(0.08);\n\nfor (const price of prices) {\n totals.push(withTax(price));\n}\n```\n\n**✅ Hoist the invariant**\n```ts\nconst TAX_RATE = 1.08;\n\nfor (const price of prices) {\n totals.push(price * TAX_RATE); // Simple and clear\n}\n```\n\n**Why**: When the invariant is a simple primitive, hoisting it outside the loop is clearer than creating a curried function.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":10828,"content_sha256":"bf369298a4e1683011cb904f616067b893656f1662c79b0799ecded85cd0ae04"},{"filename":"references/defer-await.md","content":"# 4.7 Defer Await\n\nMove `await` operations into the branches where they're actually used to avoid blocking code paths that don't need them.\n\n**❌ Incorrect: blocks both branches**\n```ts\nasync function handleRequest(userId: string, skipProcessing: boolean) {\n const userData = await fetchUserData(userId);\n\n if (skipProcessing) {\n // Returns immediately but still waited for userData\n return { skipped: true };\n }\n\n // Only this branch uses userData\n return processUserData(userData);\n}\n```\n\n**✅ Correct: only blocks when needed**\n```ts\nasync function handleRequest(userId: string, skipProcessing: boolean) {\n if (skipProcessing) {\n // Returns immediately without waiting\n return { skipped: true };\n }\n\n // Fetch only when needed\n const userData = await fetchUserData(userId);\n return processUserData(userData);\n}\n```\n\nThis optimization is especially valuable when the skipped branch is frequently taken, or when the deferred operation is expensive.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":974,"content_sha256":"7bc216c75c9e076f1096e348b080d366b69a101f070b99c8c36a8433e4495766"},{"filename":"references/memoization.md","content":"# 4.3 Memoization and Redundant Calculations\n\n## Issues\n\n- Loop-invariant code inside loops\n- Repeated function calls with same arguments\n- Constant expressions computed at runtime\n- Expensive operations that could be memoized\n- Trivial operations being memoized unnecessarily\n\n## Optimizations\n\n- Hoist loop-invariant code\n- Precompute constants at module load\n- Memoize pure functions with limited input domain\n- Cache results of expensive operations\n- Avoid memoizing trivial computations\n\n## Examples\n\n### Avoid Trivial Memoization\n\n**❌ Incorrect: trivial computation**\n```ts\nconst ternMemo = memoize((pred) => pred ? 'Right!' : 'Wrong');\n```\n\n**✅ Correct: direct computation**\n```ts\nconst result = test ? 'Right!' : 'Wrong';\n```\n\n### Hoist Loop-Invariant Calculations\n\n**❌ Incorrect: calculations recomputed each iteration**\n```ts\nfor (let i = 0; i \u003c items.length; i++) {\n const prefix = config.namespace + '.';\n const multiplier = Math.PI * 2;\n process(items[i], prefix, multiplier);\n}\n```\n\n**✅ Correct: hoist outside loop**\n```ts\nconst prefix = config.namespace + '.';\nconst multiplier = Math.PI * 2;\nconst len = items.length;\n\nfor (let i = 0; i \u003c len; i++) {\n process(items[i], prefix, multiplier);\n}\n```\n\n### Precompute Constants\n\n**❌ Incorrect: compute at runtime**\n```ts\nfunction calculateArea(radius) {\n const pi = Math.PI;\n return pi * radius * radius;\n}\n```\n\n**✅ Correct: module-level constant**\n```ts\nconst PI = Math.PI;\n\nfunction calculateArea(radius) {\n return PI * radius * radius;\n}\n```\n\n### Memoize Expensive Operations\n\n**❌ Incorrect: repeated expensive calls**\n```ts\nfunction render() {\n const data = parseAndTransformData(rawData);\n return display(data);\n}\n\n// Called many times with same rawData\nrender();\nrender();\nrender();\n```\n\n**✅ Correct: memoize expensive function**\n```ts\nconst memoizedParse = memoize(parseAndTransformData);\n\nfunction render() {\n const data = memoizedParse(rawData);\n return display(data);\n}\n```\n\n### Cache Function Results\n\n**❌ Incorrect: repeated calculation**\n```ts\nfunction processItems(items) {\n for (const item of items) {\n const config = getConfig(item.type);\n apply(item, config);\n }\n}\n\nfunction getConfig(type) {\n // Expensive lookup/calculation\n return expensiveOperation(type);\n}\n```\n\n**✅ Correct: cache results**\n```ts\nfunction processItems(items) {\n const configCache = new Map();\n\n for (const item of items) {\n if (!configCache.has(item.type)) {\n configCache.set(item.type, getConfig(item.type));\n }\n const config = configCache.get(item.type);\n apply(item, config);\n }\n}\n```\n\n### Repeated Function Calls with Same Arguments\n\n**❌ Incorrect: call multiple times**\n```ts\nfunction validate(data) {\n if (isValid(data.user) && isComplete(data.user)) {\n return processUser(data.user);\n }\n return null;\n}\n\nfunction isComplete(user) {\n return isValid(user) && user.profile && user.settings;\n}\n```\n\n**✅ Correct: call once, reuse result**\n```ts\nfunction validate(data) {\n const valid = isValid(data.user);\n if (valid && isComplete(data.user, valid)) {\n return processUser(data.user);\n }\n return null;\n}\n\nfunction isComplete(user, alreadyValid = false) {\n return (alreadyValid || isValid(user)) && user.profile && user.settings;\n}\n\n## Fallback Patterns\n\nWhen memoization doesn't work or creates problems, use these alternatives:\n\n### Fallback 1: Skip memoization for trivial computations\n\n**Scenario**: Computation is so cheap that caching overhead exceeds benefit\n```ts\n// ❌ Memoization overhead > computation cost\nconst cache = new Map\u003cnumber, number>();\n\nfunction double(n: number): number {\n if (cache.has(n)) return cache.get(n)!;\n const result = n * 2;\n cache.set(n, result);\n return result;\n}\n```\n\n**✅ Just compute directly**\n```ts\nfunction double(n: number): number {\n return n * 2;\n}\n```\n\n**When to skip memoization**:\n- Simple arithmetic (addition, multiplication, modulo)\n- Property access on in-memory objects\n- String concatenation of short strings\n- Array index lookups\n\n**Why**: Map overhead (hashing, storage, lookup) exceeds cost of trivial operations. Memoize only when computation cost significantly exceeds cache overhead.\n\n### Fallback 2: Limit cache size to prevent memory leaks\n\n**Scenario**: Cache grows unbounded and causes memory exhaustion\n```ts\n// ❌ Unbounded cache can leak memory\nconst cache = new Map\u003cstring, Result>();\n\nfunction compute(input: string): Result {\n if (cache.has(input)) return cache.get(input)!;\n const result = expensiveOperation(input);\n cache.set(input, result); // Cache grows forever\n return result;\n}\n```\n\n**✅ Use LRU cache with size limit**\n```ts\nclass LRUCache\u003cK, V> {\n private cache = new Map\u003cK, V>();\n private order: K[] = [];\n\n constructor(private maxSize: number = 100) {}\n\n get(key: K): V | undefined {\n const value = this.cache.get(key);\n if (value !== undefined) {\n // Move to end (most recently used)\n this.order = this.order.filter(k => k !== key);\n this.order.push(key);\n }\n return value;\n }\n\n set(key: K, value: V): void {\n if (this.cache.has(key)) {\n this.order = this.order.filter(k => k !== key);\n } else if (this.cache.size >= this.maxSize) {\n // Evict least recently used\n const oldest = this.order.shift()!;\n this.cache.delete(oldest);\n }\n\n this.cache.set(key, value);\n this.order.push(key);\n }\n}\n\nconst cache = new LRUCache\u003cstring, Result>(100);\n\nfunction compute(input: string): Result {\n const cached = cache.get(input);\n if (cached) return cached;\n\n const result = expensiveOperation(input);\n cache.set(input, result);\n return result;\n}\n```\n\n**Why**: Unbounded caches leak memory. LRU (Least Recently Used) eviction maintains fixed memory usage while keeping hot data cached.\n\n### Fallback 3: Time-based cache invalidation for stale data\n\n**Scenario**: Cached data becomes stale and must be refreshed\n```ts\n// ❌ Cache never expires, returns stale data\nconst cache = new Map\u003cstring, UserData>();\n\nfunction getUserData(userId: string): UserData {\n if (cache.has(userId)) return cache.get(userId)!;\n const data = fetchUserData(userId);\n cache.set(userId, data);\n return data;\n}\n```\n\n**✅ Add TTL (time-to-live) to cache entries**\n```ts\ninterface CacheEntry\u003cT> {\n value: T;\n expires: number;\n}\n\nconst TTL_MS = 5 * 60 * 1000; // 5 minutes\nconst cache = new Map\u003cstring, CacheEntry\u003cUserData>>();\n\nfunction getUserData(userId: string): UserData {\n const entry = cache.get(userId);\n const now = Date.now();\n\n if (entry && entry.expires > now) {\n return entry.value; // Still valid\n }\n\n const data = fetchUserData(userId);\n cache.set(userId, {\n value: data,\n expires: now + TTL_MS,\n });\n\n return data;\n}\n```\n\n**Why**: Some data changes over time (user profiles, prices, inventory). TTL ensures cache freshness without manual invalidation.\n\n### Fallback 4: Recompute instead of complex cache key generation\n\n**Scenario**: Cache key generation is expensive or complex\n```ts\n// ❌ Complex cache key generation\nconst cache = new Map\u003cstring, Result>();\n\nfunction process(obj: ComplexObject): Result {\n // Expensive: serialize entire object to create key\n const key = JSON.stringify(obj);\n if (cache.has(key)) return cache.get(key)!;\n\n const result = expensiveOperation(obj);\n cache.set(key, result);\n return result;\n}\n```\n\n**✅ Skip memoization, just recompute**\n```ts\nfunction process(obj: ComplexObject): Result {\n return expensiveOperation(obj);\n}\n```\n\n**When to skip memoization due to key complexity**:\n- Cache key requires serialization (JSON.stringify, hash computation)\n- Objects are large or deeply nested\n- Key generation cost approaches computation cost\n\n**Why**: If key generation (serialization, hashing) costs 80% of the computation, memoization provides minimal benefit. Only memoize when key generation is trivial compared to computation.\n\n### Fallback 5: Use WeakMap for object-keyed caches\n\n**Scenario**: Caching results keyed by objects, need automatic cleanup\n```ts\n// ❌ Regular Map prevents garbage collection\nconst cache = new Map\u003cobject, Result>();\n\nfunction process(obj: SomeObject): Result {\n if (cache.has(obj)) return cache.get(obj)!;\n const result = expensiveOperation(obj);\n cache.set(obj, result); // obj can never be GC'd\n return result;\n}\n```\n\n**✅ Use WeakMap for automatic cleanup**\n```ts\nconst cache = new WeakMap\u003cobject, Result>();\n\nfunction process(obj: SomeObject): Result {\n const cached = cache.get(obj);\n if (cached) return cached;\n\n const result = expensiveOperation(obj);\n cache.set(obj, result);\n return result;\n}\n\n// When obj goes out of scope, cache entry is automatically removed\n```\n\n**Why**: WeakMap allows garbage collection of keys. When the object is no longer referenced elsewhere, the cache entry is automatically cleaned up, preventing memory leaks.\n\n### Fallback 6: Precomputation instead of runtime memoization\n\n**Scenario**: All possible inputs are known ahead of time\n```ts\n// ❌ Compute and cache at runtime\nconst cache = new Map\u003cnumber, number>();\n\nfunction factorial(n: number): number {\n if (cache.has(n)) return cache.get(n)!;\n const result = n \u003c= 1 ? 1 : n * factorial(n - 1);\n cache.set(n, result);\n return result;\n}\n```\n\n**✅ Precompute all values at startup**\n```ts\n// Precompute factorials for n = 0 to 20\nconst FACTORIALS = [\n 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880,\n 3628800, 39916800, 479001600, 6227020800, 87178291200,\n 1307674368000, 20922789888000, 355687428096000,\n 6402373705728000, 121645100408832000, 2432902008176640000\n];\n\nfunction factorial(n: number): number {\n if (n \u003c 0 || n >= FACTORIALS.length) {\n throw new Error(`Factorial(${n}) out of range [0, ${FACTORIALS.length - 1}]`);\n }\n return FACTORIALS[n];\n}\n```\n\n**When to precompute**:\n- Input space is small and finite (\u003c 1000 values)\n- All inputs are known at compile time\n- Computation is expensive but only needs to run once\n\n**Why**: Precomputation eliminates runtime overhead (cache checks, storage). Array lookup is faster than Map lookup. Memory cost is paid upfront and constant.\n```\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":10082,"content_sha256":"6759c8340dee93bab9c26532123bf623b6eef66d9827b7a8c99ca8d4af78fc3b"},{"filename":"references/object-operations.md","content":"# 4.10 Object Operations\n\n## Issues\n\n- Object spreading in loops\n- Deep cloning when shallow clone suffices\n- Unnecessary object creation\n- Object.keys/values/entries on hot paths\n- Spread operators for single property changes\n\n## Optimizations\n\n- Mutate when safe (function owns object, local scope, not returned/exposed)\n- Use Object.assign for shallow updates when immutability required\n- Preallocate objects with known shape\n- Direct property assignment over spreading when object is owned\n\n## Examples\n\n### Mutate When Safe\n\n**❌ Incorrect: unnecessary spread in loop**\n```ts\nlet result = {};\nfor (const item of items) {\n result = { ...result, [item.id]: item.value };\n}\n```\n\n**✅ Correct: mutate owned object**\n```ts\nconst result = {};\nfor (const item of items) {\n result[item.id] = item.value;\n}\n```\n\n### Shallow vs Deep Clone\n\n**❌ Incorrect: deep clone for simple update**\n```ts\nimport { cloneDeep } from 'lodash';\n\nfunction updateUser(user, name) {\n const updated = cloneDeep(user);\n updated.name = name;\n return updated;\n}\n```\n\n**✅ Correct: shallow clone with Object.assign**\n```ts\nfunction updateUser(user, name) {\n return Object.assign({}, user, { name });\n}\n```\n\n### Single Property Update\n\n**❌ Incorrect: spread for one property**\n```ts\nfunction setActive(state, active) {\n return {\n ...state,\n active,\n };\n}\n```\n\n**✅ Correct: Object.assign for performance**\n```ts\nfunction setActive(state, active) {\n return Object.assign({}, state, { active });\n}\n```\n\n### Preallocate Object Shape\n\n**❌ Incorrect: dynamic property addition**\n```ts\nfunction buildConfig(data) {\n const config = {};\n if (data.x) config.x = data.x;\n if (data.y) config.y = data.y;\n if (data.z) config.z = data.z;\n return config;\n}\n```\n\n**✅ Correct: preallocate shape**\n```ts\nfunction buildConfig(data) {\n return {\n x: data.x || 0,\n y: data.y || 0,\n z: data.z || 0,\n };\n}\n```\n\n### Object.keys on Hot Paths\n\n**❌ Incorrect: repeated Object.keys**\n```ts\nfor (const item of items) {\n const keys = Object.keys(item);\n if (keys.length > 0) {\n process(item);\n }\n}\n```\n\n**✅ Correct: use for...in or check properties directly**\n```ts\nfor (const item of items) {\n if (item.id !== undefined) {\n process(item);\n }\n}\n```\n\n### Unnecessary Object Creation\n\n**❌ Incorrect: create object just to destructure**\n```ts\nfunction getCoords(x, y) {\n const point = { x, y };\n return processPoint(point);\n}\n\nfunction processPoint({ x, y }) {\n return Math.sqrt(x * x + y * y);\n}\n```\n\n**✅ Correct: pass values directly**\n```ts\nfunction getCoords(x, y) {\n return processPoint(x, y);\n}\n\nfunction processPoint(x, y) {\n return Math.sqrt(x * x + y * y);\n}\n```\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":2675,"content_sha256":"f6ae4913c185c5004f2c04ab8356cdd9616962c57194bc06900f35e0f9bba3ea"},{"filename":"references/performance-misc.md","content":"# 4.11 Additional Performance Concerns\n\n## Issues\n\n- String concatenation in loops (use array join)\n- Regular expression creation in loops\n- Synchronous I/O on hot paths\n- Unnecessary async/await overhead\n- try/catch in tight loops (deoptimization risk)\n- Closures capturing large scopes\n- Function bind/arrow functions in render paths\n\n## Optimizations\n\n- Batch string operations\n- Compile regex once, reuse\n- Use async I/O with proper batching\n- Remove unnecessary async wrappers\n- Move error handling outside hot loops\n- Minimize closure scope\n- Prebind functions outside loops/renders\n\n## Examples\n\n### String Building with Array Join\n\nString concatenation creates new strings on each operation. Use array join for building strings in loops.\n\n**❌ Incorrect: repeated string concatenation**\n```ts\nlet result = '';\nfor (const item of items) {\n result += item.name + ', ';\n}\n```\n\n**✅ Correct: array join**\n```ts\nconst parts = [];\nfor (const item of items) {\n parts.push(item.name);\n}\nconst result = parts.join(', ');\n```\n\n### Regular Expression in Loops\n\n**❌ Incorrect: create regex each iteration**\n```ts\nfor (const text of texts) {\n const matches = text.match(/\\d+/g);\n process(matches);\n}\n```\n\n**✅ Correct: compile once**\n```ts\nconst digitRegex = /\\d+/g;\nfor (const text of texts) {\n const matches = text.match(digitRegex);\n process(matches);\n}\n```\n\n### Unnecessary Async Overhead\n\n**❌ Incorrect: async wrapper with no await**\n```ts\nasync function getUser(id) {\n return users.find(u => u.id === id);\n}\n```\n\n**✅ Correct: synchronous function**\n```ts\nfunction getUser(id) {\n return users.find(u => u.id === id);\n}\n```\n\n### try/catch in Tight Loops\n\n**❌ Incorrect: error handling in loop**\n```ts\nfor (let i = 0; i \u003c items.length; i++) {\n try {\n process(items[i]);\n } catch (err) {\n logError(err);\n }\n}\n```\n\n**✅ Correct: move error handling outside**\n```ts\ntry {\n for (let i = 0; i \u003c items.length; i++) {\n process(items[i]);\n }\n} catch (err) {\n logError(err);\n}\n\n// Or handle errors in the called function\n```\n\n### Closures Capturing Large Scopes\n\n**❌ Incorrect: capture entire context**\n```ts\nfunction createProcessor(largeConfig) {\n return function process(item) {\n return item.value * largeConfig.data.nested.multiplier;\n };\n}\n```\n\n**✅ Correct: minimize closure scope**\n```ts\nfunction createProcessor(largeConfig) {\n const multiplier = largeConfig.data.nested.multiplier;\n return function process(item) {\n return item.value * multiplier;\n };\n}\n```\n\n### Function Bind in Render Paths\n\n**❌ Incorrect: create new function each render**\n```ts\nfunction Component({ items }) {\n return items.map(item => (\n \u003cbutton onClick={() => handleClick(item.id)}>\n {item.name}\n \u003c/button>\n ));\n}\n```\n\n**✅ Correct: prebind or use data attributes**\n```ts\nfunction Component({ items }) {\n const handleItemClick = (e) => {\n handleClick(e.target.dataset.id);\n };\n\n return items.map(item => (\n \u003cbutton onClick={handleItemClick} data-id={item.id}>\n {item.name}\n \u003c/button>\n ));\n}\n```\n\n### Async I/O on Hot Paths\n\n**❌ Incorrect: synchronous blocking**\n```ts\nimport { readFileSync } from 'fs';\n\nfunction loadTemplate(name) {\n return readFileSync(`./templates/${name}.html`, 'utf-8');\n}\n\n// Called in request handler\napp.get('/page', (req, res) => {\n const template = loadTemplate('home');\n res.send(template);\n});\n```\n\n**✅ Correct: async with caching**\n```ts\nimport { readFile } from 'fs/promises';\n\nconst templateCache = new Map();\n\nasync function loadTemplate(name) {\n if (!templateCache.has(name)) {\n const content = await readFile(`./templates/${name}.html`, 'utf-8');\n templateCache.set(name, content);\n }\n return templateCache.get(name);\n}\n\napp.get('/page', async (req, res) => {\n const template = await loadTemplate('home');\n res.send(template);\n});\n```\n\n### Template Literals vs Array Join\n\nFor complex string building with many parts, array join can be more efficient than template literals.\n\n**❌ Incorrect: multiple concatenations per iteration**\n```ts\nfunction buildHTML(items) {\n let html = '\u003cul>';\n for (const item of items) {\n html += '\u003cli>' + item.name + '\u003c/li>';\n }\n html += '\u003c/ul>';\n return html;\n}\n```\n\n**✅ Correct: array join (better for many items)**\n```ts\nfunction buildHTML(items) {\n const parts = ['\u003cul>'];\n for (const item of items) {\n parts.push('\u003cli>', item.name, '\u003c/li>');\n }\n parts.push('\u003c/ul>');\n return parts.join('');\n}\n```\n\n**Note**: For small iterations (\u003c100 items) or simple concatenations, template literals are fine and more readable.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4573,"content_sha256":"f4f05aee4b12bc85a72a546f4a5e0224ba906393b9cfc4fbb00a19dc517b7265"},{"filename":"references/predictable-execution.md","content":"# 4.5 Predictable Execution and Cache Locality\n\n## Issues\n\n- Poor data structure layout for access pattern\n- Random access patterns that could be sequential\n- Struct-of-arrays vs array-of-structs mismatches\n- Scattered memory access in tight loops\n- Unpredictable control flow\n\n## Optimizations\n\n- Sequential memory access patterns\n- Group related data together\n- Use flat arrays instead of nested structures\n- Consider columnar layout for analytics workloads\n- Write code with clear, predictable execution paths\n\n## Examples\n\n### Sequential vs Random Access\n\n**❌ Incorrect: random access pattern**\n```ts\nconst users = new Map();\nusers.set('id1', { name: 'Alice', age: 30 });\nusers.set('id2', { name: 'Bob', age: 25 });\n\n// Random access through Map\nfor (const id of shuffledIds) {\n process(users.get(id));\n}\n```\n\n**✅ Correct: sequential access**\n```ts\nconst users = [\n { id: 'id1', name: 'Alice', age: 30 },\n { id: 'id2', name: 'Bob', age: 25 },\n];\n\n// Sequential memory access\nfor (let i = 0; i \u003c users.length; i++) {\n process(users[i]);\n}\n```\n\n### Struct-of-Arrays vs Array-of-Structs\n\n**❌ Incorrect: array-of-structs for columnar access**\n```ts\nconst particles = [\n { x: 1, y: 2, vx: 0.1, vy: 0.2 },\n { x: 3, y: 4, vx: 0.3, vy: 0.4 },\n // ... thousands more\n];\n\n// Need only x coordinates - poor cache usage\nfor (let i = 0; i \u003c particles.length; i++) {\n updateX(particles[i].x);\n}\n```\n\n**✅ Correct: struct-of-arrays for columnar workload**\n```ts\nconst particles = {\n x: [1, 3, ...],\n y: [2, 4, ...],\n vx: [0.1, 0.3, ...],\n vy: [0.2, 0.4, ...],\n};\n\n// Sequential access to contiguous memory\nfor (let i = 0; i \u003c particles.x.length; i++) {\n updateX(particles.x[i]);\n}\n```\n\n### Flat Arrays vs Nested Structures\n\n**❌ Incorrect: nested object access**\n```ts\nconst grid = {\n rows: [\n { cells: [{ value: 1 }, { value: 2 }] },\n { cells: [{ value: 3 }, { value: 4 }] },\n ]\n};\n\nfor (const row of grid.rows) {\n for (const cell of row.cells) {\n process(cell.value);\n }\n}\n```\n\n**✅ Correct: flat array**\n```ts\nconst values = [1, 2, 3, 4];\nconst width = 2;\n\nfor (let i = 0; i \u003c values.length; i++) {\n process(values[i]);\n}\n```\n\n### Group Related Data\n\n**❌ Incorrect: scattered data access**\n```ts\nconst ids = [1, 2, 3];\nconst names = ['Alice', 'Bob', 'Charlie'];\nconst ages = [30, 25, 35];\n\nfor (let i = 0; i \u003c ids.length; i++) {\n processUser(ids[i], names[i], ages[i]);\n}\n```\n\n**✅ Correct: grouped data**\n```ts\nconst users = [\n { id: 1, name: 'Alice', age: 30 },\n { id: 2, name: 'Bob', age: 25 },\n { id: 3, name: 'Charlie', age: 35 },\n];\n\nfor (let i = 0; i \u003c users.length; i++) {\n const user = users[i];\n processUser(user.id, user.name, user.age);\n}\n```\n\n### Predictable Control Flow\n\n**❌ Incorrect: unpredictable branches**\n```ts\nfunction process(items) {\n for (const item of items) {\n if (Math.random() > 0.5) {\n handleA(item);\n } else {\n handleB(item);\n }\n }\n}\n```\n\n**✅ Correct: predictable branches**\n```ts\nfunction process(items) {\n for (const item of items) {\n if (item.type === 'A') {\n handleA(item);\n } else {\n handleB(item);\n }\n }\n}\n```\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":3130,"content_sha256":"f291d2e93bcceca97a36203d9eec3ff502a0e586cfb8b2615a05d05839b2b18d"},{"filename":"references/quick-reference.md","content":"# Quick Optimization Reference\n\nQuick lookup for common performance bottleneck patterns and optimization categories.\n\n## Bottleneck → Category Mapping\n\n### Nested Loops (O(n²) Complexity)\n\n**Symptoms:**\n- Multiple nested `for` loops\n- `.filter()` inside `.map()` or other array methods\n- Array methods called inside loops\n- Linear search (`.includes()`, `.find()`) in hot paths\n\n**Category:** Algorithmic optimization\n\n**Reference files:**\n- [reduce-looping.md](reduce-looping.md)\n- [reduce-branching.md](reduce-branching.md)\n\n**Expected speedup:** 10-1000x for large datasets\n\n---\n\n### Repeated Expensive Computations\n\n**Symptoms:**\n- Same calculation performed multiple times\n- Function called with same arguments repeatedly\n- Computed values recalculated in loops\n- Invariant operations inside loops\n\n**Category:** Caching & memoization\n\n**Reference files:**\n- [memoization.md](memoization.md)\n- [cache-property-access.md](cache-property-access.md)\n\n**Expected speedup:** 2-100x depending on computation cost\n\n---\n\n### Allocation-Heavy Code\n\n**Symptoms:**\n- Many small object creations in loops\n- Excessive use of spread operator (`...`)\n- Creating temporary arrays (`.slice()`, `[...arr]`)\n- String concatenation in loops\n- Frequent garbage collection (visible in profiler)\n\n**Category:** Allocation reduction\n\n**Reference files:**\n- [avoid-allocations.md](avoid-allocations.md)\n- [object-operations.md](object-operations.md)\n\n**Expected speedup:** 1.5-5x plus reduced GC pauses\n\n---\n\n### Storage API in Loops\n\n**Symptoms:**\n- `localStorage.getItem()` in loops or hot paths\n- `sessionStorage` reads inside iterations\n- Cookie parsing on every function call\n- Storage API calls not cached\n\n**Category:** Caching\n\n**Reference files:**\n- [cache-storage-api.md](cache-storage-api.md)\n\n**Expected speedup:** 5-20x for storage-heavy operations\n\n---\n\n### Sequential Async Operations\n\n**Symptoms:**\n- Multiple `await` statements in sequence\n- `await` before conditional branches\n- Promise chains that could be parallel\n- Blocking on I/O that could be deferred\n\n**Category:** I/O optimization\n\n**Reference files:**\n- [defer-await.md](defer-await.md)\n- [batching.md](batching.md)\n\n**Expected speedup:** 2-10x for I/O-bound operations\n\n---\n\n### Poor Memory Locality\n\n**Symptoms:**\n- Random access patterns in arrays\n- Non-sequential iteration\n- Struct of Arrays could be Array of Structs\n- Cache misses visible in profiler\n\n**Category:** Memory locality\n\n**Reference files:**\n- [predictable-execution.md](predictable-execution.md)\n\n**Expected speedup:** 1.5-3x for large datasets\n\n---\n\n### Unbounded Iterations\n\n**Symptoms:**\n- Loops without maximum iteration counts\n- Queue processing without bounds\n- Recursive functions without depth limits\n- User input controls iteration count\n\n**Category:** Bounded execution\n\n**Reference files:**\n- [bounded-iteration.md](bounded-iteration.md)\n\n**Expected speedup:** Prevents pathological cases (DoS prevention)\n\n---\n\n## Profiler Output → Category Lookup\n\n| Profiler Shows | Issue Type | Category | Reference Files |\n|----------------|------------|----------|-----------------|\n| `Array.prototype.filter` high % | Chained array methods | Algorithmic | [reduce-looping.md](reduce-looping.md) |\n| `Map.get` in tight loop | Should cache lookup | Caching | [cache-property-access.md](cache-property-access.md) |\n| `Object.assign` / spread high % | Object allocation | Allocation | [object-operations.md](object-operations.md), [avoid-allocations.md](avoid-allocations.md) |\n| `localStorage.getItem` frequent | Storage not cached | Caching | [cache-storage-api.md](cache-storage-api.md) |\n| Long async function | Sequential awaits | I/O | [defer-await.md](defer-await.md) |\n| GC taking >10% time | Allocation pressure | Allocation | [avoid-allocations.md](avoid-allocations.md) |\n| Random access pattern | Poor locality | Memory locality | [predictable-execution.md](predictable-execution.md) |\n| Nested loop consuming >20% | O(n²) algorithm | Algorithmic | [reduce-looping.md](reduce-looping.md), [reduce-branching.md](reduce-branching.md) |\n\n---\n\n## Decision Matrix: When to Optimize\n\n```\n┌─────────────────────────────────────────┐\n│ Is profiler showing >5% time in code? │\n└─────────┬───────────────────────────────┘\n │\n ├─ NO ──→ Don't optimize (not a bottleneck)\n │\n └─ YES ──→ What's the issue?\n │\n ├─ O(n²) or worse ──→ Algorithmic fix (10-1000x)\n │ reduce-looping.md, reduce-branching.md\n │\n ├─ Repeated computation ──→ Caching (2-100x)\n │ memoization.md, cache-property-access.md\n │\n ├─ Many allocations ──→ Reduce GC (1.5-5x)\n │ avoid-allocations.md, object-operations.md\n │\n ├─ Sequential I/O ──→ Parallel/defer (2-50x)\n │ defer-await.md, batching.md\n │\n └─ Loop overhead ──→ Micro-optimization (1.05-2x)\n currying.md, performance-misc.md\n Only if hot path!\n```\n\n---\n\n## Anti-Pattern Detection\n\n**Before loading any references, scan for these common anti-patterns and identify categories:**\n\n```typescript\n// ❌ O(n²) - Category: Algorithmic\n// References: reduce-looping.md, reduce-branching.md\nfor (const item of itemsA) {\n const match = itemsB.find(x => x.id === item.id);\n}\n\n// ❌ Repeated expensive computation - Category: Caching\n// References: memoization.md, cache-property-access.md\nfor (let i = 0; i \u003c array.length; i++) {\n const result = expensiveFunction(sameInput);\n}\n\n// ❌ Property access in loop - Category: Caching\n// References: cache-property-access.md\nfor (let i = 0; i \u003c items.length; i++) {\n process(config.settings.nested.property);\n}\n\n// ❌ Storage API not cached - Category: Caching\n// References: cache-storage-api.md\nfunction getValue() {\n return JSON.parse(localStorage.getItem('key') || '{}');\n}\n\n// ❌ Sequential awaits - Category: I/O\n// References: defer-await.md, batching.md\nasync function process() {\n const a = await fetchA();\n const b = await fetchB(); // Could be parallel\n return combine(a, b);\n}\n\n// ❌ Allocation in loop - Category: Allocation\n// References: avoid-allocations.md, object-operations.md\nconst results = [];\nfor (const item of items) {\n results.push({ ...item, newProp: value }); // Spread creates new object\n}\n```\n\n**When you see these patterns:**\n1. Identify the category from the comments\n2. Load the reference files listed for that category\n3. Find optimization patterns in the reference files\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":7072,"content_sha256":"d6cd7d1f780dd90662f876c3000fd6ec0fc13b82974bbbb5f43d9411d436d656"},{"filename":"references/reduce-branching.md","content":"# 4.1 Reduce Branching\n\n## Issues\n\n- Excessive nested conditionals (>3 levels)\n- Switch statements that could be lookup tables\n- Repeated condition checks in same scope\n- Polymorphic branching on hot paths\n- Type guards that could be avoided\n\n## Optimizations\n\n- Convert switch/if-chains to object/Map lookups\n- Hoist invariant conditions\n- Use early returns to reduce nesting\n- Replace runtime type checks with compile-time guarantees\n\n## Examples\n\n### Switch to Lookup Table\n\n**❌ Incorrect: conditional checks**\n```ts\nif (thing === 'ONE') {\n /*...*/\n}\n\nif (thing === 'TWO') {\n /*...*/\n}\n\nif (thing === 'THREE') {\n /*...*/\n}\n```\n\n**✅ Correct: lookup table**\n```ts\nconst lookup = {\n ONE: {/*...*/},\n TWO: {/*...*/},\n THREE: {/*...*/},\n}\n\nconst action = lookup[thing];\n```\n\n### Nested Conditionals to Early Returns\n\n**❌ Incorrect: excessive nesting**\n```ts\nfunction process(data) {\n if (data) {\n if (data.isValid) {\n if (data.user) {\n if (data.user.hasPermission) {\n return doWork(data);\n }\n }\n }\n }\n return null;\n}\n```\n\n**✅ Correct: early returns**\n```ts\nfunction process(data) {\n if (!data) return null;\n if (!data.isValid) return null;\n if (!data.user) return null;\n if (!data.user.hasPermission) return null;\n\n return doWork(data);\n}\n```\n\n### Hoist Invariant Conditions\n\n**❌ Incorrect: repeated checks**\n```ts\nfor (const item of items) {\n if (config.enableFeature && item.active) {\n process(item);\n }\n}\n```\n\n**✅ Correct: hoist invariant**\n```ts\nif (config.enableFeature) {\n for (const item of items) {\n if (item.active) {\n process(item);\n }\n }\n}\n```\n\n### Runtime Type Checks to Compile-Time\n\n**❌ Incorrect: runtime branching**\n```ts\nfunction format(value: string | number) {\n if (typeof value === 'string') {\n return value.toUpperCase();\n } else {\n return value.toFixed(2);\n }\n}\n```\n\n**✅ Correct: separate functions**\n```ts\nfunction formatString(value: string): string {\n return value.toUpperCase();\n}\n\nfunction formatNumber(value: number): string {\n return value.toFixed(2);\n}\n```\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":2083,"content_sha256":"179fa9774b0c5912af01598f6befe052a0b7ad5c044b5b9f11babafc22484be7"},{"filename":"references/reduce-looping.md","content":"# 4.2 Reduce Looping\n\n## Issues\n\n- Multiple passes over same array (`.map().filter().reduce()`)\n- Unnecessary array creation (spreading, slicing)\n- Array methods in loops\n- Linear searches that could use Sets/Maps\n- Incorrect collection type for access pattern\n\n## Optimizations\n\n- Combine multiple array operations into single pass\n- Use index-based loops for performance-critical paths\n- Replace O(n) lookups with O(1) using Set/Map\n- Use typed arrays for numeric data\n- Reuse arrays when function owns them (local scope, not returned/exposed)\n\n## Examples\n\n### Chained Methods to Single Reduce\n\n**❌ Incorrect: multiple passes over array**\n```ts\nconst result = arr.filter(predicate).map(mapper);\n// Pass 1: filter creates intermediate array\n// Pass 2: map creates final array\n```\n\n**✅ Correct: single pass**\n```ts\nconst result = arr.reduce((acc, curr) =>\n predicate(curr) ? [...acc, mapper(curr)] : acc,\n []\n);\n// Single pass: test and transform in one iteration\n```\n\n**Why this matters**: Each array method creates a new array and iterates all elements. For large arrays, this means:\n- Extra memory allocation for intermediate arrays\n- Cache misses from jumping between arrays\n- Double the loop overhead (iterator setup, bounds checks)\n\nFor 10,000 items, chaining `.filter().map()` means 20,000+ iterations plus temporary array allocation. Single `reduce` = 10,000 iterations, zero intermediate arrays.\n\n### Linear Search to O(1) Lookup\n\n**❌ Incorrect: O(n) - searches entire array every time**\n```ts\nconst keys = Object.keys(someObj);\nif (keys.includes(id)) { /**/ }\n\n// In a loop, this becomes O(n * m):\nfor (const id of userIds) { // n iterations\n if (keys.includes(id)) { /**/ } // m lookups each\n}\n```\n\n**✅ Correct: O(1) - hash lookup**\n```ts\nconst keys = new Set(Object.keys(someObj));\nif (keys.has(id)) { /**/ }\n\n// In a loop, this is O(n + m):\nfor (const id of userIds) { // n iterations\n if (keys.has(id)) { /**/ } // O(1) lookup each\n}\n```\n\n**Why this matters**: `Array.includes()` scans the entire array linearly. For 100 items and 100 lookups, that's 10,000 comparisons. `Set.has()` uses hashing for O(1) lookups: 100 items and 100 lookups = 200 operations (100 to build Set, 100 to lookup). That's a **50x speedup**.\n\n### Array Methods in Loops\n\n**❌ Incorrect: nested iterations**\n```ts\nfor (const user of users) {\n const active = items.filter(item => item.userId === user.id);\n process(active);\n}\n```\n\n**✅ Correct: build lookup once**\n```ts\nconst itemsByUser = new Map();\nfor (const item of items) {\n if (!itemsByUser.has(item.userId)) {\n itemsByUser.set(item.userId, []);\n }\n itemsByUser.get(item.userId).push(item);\n}\n\nfor (const user of users) {\n const active = itemsByUser.get(user.id) || [];\n process(active);\n}\n```\n\n### Unnecessary Array Creation\n\n**❌ Incorrect: creates intermediate arrays**\n```ts\nconst result = [...arr].slice(0, 10).map(transform);\n```\n\n**✅ Correct: process directly**\n```ts\nconst result = [];\nconst len = Math.min(arr.length, 10);\nfor (let i = 0; i \u003c len; i++) {\n result.push(transform(arr[i]));\n}\n```\n\n### Index-Based Loops for Hot Paths\n\n**❌ Incorrect: slower iteration**\n```ts\nfor (const item of largeArray) {\n // performance-critical operation\n processPixel(item);\n}\n```\n\n**✅ Correct: index-based**\n```ts\nconst len = largeArray.length;\nfor (let i = 0; i \u003c len; i++) {\n processPixel(largeArray[i]);\n}\n```\n\n### Typed Arrays for Numeric Data\n\n**❌ Incorrect: generic array stores boxed numbers**\n```ts\nconst pixels = new Array(width * height);\nfor (let i = 0; i \u003c pixels.length; i++) {\n pixels[i] = Math.random() * 255;\n}\n// Each number is a heap-allocated object\n// Array can contain mixed types (slow property access)\n```\n\n**✅ Correct: typed array uses contiguous memory**\n```ts\nconst pixels = new Uint8Array(width * height);\nfor (let i = 0; i \u003c pixels.length; i++) {\n pixels[i] = Math.random() * 255;\n}\n// Fixed-type, contiguous memory buffer\n// Direct memory access without boxing\n```\n\n**Why this matters**:\n\n1. **Memory efficiency**: Generic arrays store numbers as heap-allocated objects (~16 bytes each). Typed arrays use raw bytes (1 byte for Uint8, 4 bytes for Float32). For 1920×1080 image: generic array = ~31MB, Uint8Array = 2MB.\n\n2. **Cache locality**: Typed arrays are contiguous memory buffers. CPU can prefetch and cache efficiently. Generic arrays are pointer arrays - each access may cause cache miss.\n\n3. **Predictable performance**: V8 can't optimize generic arrays if types change. Typed arrays are monomorphic by definition - V8 generates optimal machine code.\n\nUse typed arrays for: pixel data, audio samples, 3D coordinates, binary protocols, large numeric datasets.\n\n## Fallback Patterns\n\nWhen the primary optimization doesn't work, use these alternatives:\n\n### Fallback 1: Keep chained methods for readability in cold paths\n\n**Scenario**: Code runs infrequently or with small datasets\n```ts\n// In configuration loading (runs once at startup)\nconst activeUsers = users\n .filter(u => u.status === 'active')\n .map(u => u.name)\n .sort();\n```\n\n**When to keep chained methods**:\n- Non-performance-critical code (configuration, initialization)\n- Small datasets (\u003c 100 items)\n- Readability is more valuable than microsecond gains\n\n**Why**: Single-pass reduce is harder to read. In cold paths with small data, clarity trumps optimization.\n\n### Fallback 2: Use `for` loop when reduce becomes unreadable\n\n**Scenario**: Complex logic makes reduce hard to understand\n```ts\n// ❌ Reduce is technically correct but hard to parse\nconst result = items.reduce((acc, item) => {\n if (item.active && item.score > 50) {\n const processed = processItem(item);\n if (processed.valid) {\n acc.valid.push(processed);\n } else {\n acc.invalid.push(item.id);\n }\n }\n return acc;\n}, { valid: [], invalid: [] });\n```\n\n**✅ Use explicit for loop**\n```ts\nconst result = { valid: [], invalid: [] };\n\nfor (const item of items) {\n if (!item.active || item.score \u003c= 50) continue;\n\n const processed = processItem(item);\n if (processed.valid) {\n result.valid.push(processed);\n } else {\n result.invalid.push(item.id);\n }\n}\n```\n\n**Why**: When reduce logic becomes nested or complex, explicit loops are clearer. Performance difference is minimal, readability difference is significant.\n\n### Fallback 3: Keep Set.has() but add graceful degradation\n\n**Scenario**: Set might contain many items, memory becomes a concern\n```ts\n// ❌ Set could consume excessive memory for very large datasets\nconst keys = new Set(allKeys); // allKeys has 10M items\n\nfor (const id of userIds) {\n if (keys.has(id)) { /* ... */ }\n}\n```\n\n**✅ Add size check and fallback**\n```ts\nconst MAX_SET_SIZE = 100000;\nlet lookup: Set\u003cstring> | string[];\n\nif (allKeys.length > MAX_SET_SIZE) {\n // Fall back to sorted array with binary search\n lookup = [...new Set(allKeys)].sort();\n} else {\n lookup = new Set(allKeys);\n}\n\nfunction contains(id: string): boolean {\n if (lookup instanceof Set) {\n return lookup.has(id);\n }\n\n // Binary search on sorted array\n let left = 0;\n let right = lookup.length - 1;\n\n while (left \u003c= right) {\n const mid = Math.floor((left + right) / 2);\n if (lookup[mid] === id) return true;\n if (lookup[mid] \u003c id) {\n left = mid + 1;\n } else {\n right = mid - 1;\n }\n }\n\n return false;\n}\n```\n\n**Why**: Set.has() is O(1) but uses ~10x memory per element compared to arrays. For very large datasets, sorted array with binary search (O(log n)) may be better.\n\n### Fallback 4: Use Array.includes() with small arrays\n\n**Scenario**: Array has few items and won't grow\n```ts\n// ✅ Array.includes() is fine here\nconst ALLOWED_METHODS = ['GET', 'POST', 'PUT', 'DELETE'];\n\nif (ALLOWED_METHODS.includes(method)) {\n // Only 4 items - Set overhead not worth it\n}\n```\n\n**When Array.includes() is acceptable**:\n- Array has \u003c 10 items\n- Array is constant (not built dynamically)\n- Lookup happens infrequently\n\n**Why**: Set overhead (construction, memory) exceeds benefit for small constant arrays. Linear search of 10 items is faster than Set construction.\n\n### Fallback 5: Typed arrays with fallback for compatibility\n\n**Scenario**: Need typed array performance but must support old environments\n```ts\nfunction createBuffer(size: number): Uint8Array | number[] {\n try {\n return new Uint8Array(size);\n } catch {\n // Fall back to regular array in environments without TypedArray support\n return new Array(size).fill(0);\n }\n}\n\nfunction setValue(buffer: Uint8Array | number[], index: number, value: number): void {\n buffer[index] = Math.floor(value) & 0xFF; // Works for both types\n}\n```\n\n**Why**: Typed arrays aren't supported everywhere. Graceful degradation maintains functionality while optimizing for modern environments.\n\n### Fallback 6: Index-based loop with early exit\n\n**Scenario**: Need to stop iteration early, `for...of` doesn't allow break with value\n```ts\n// ❌ for...of doesn't work well with early exit + return value\nfunction findFirstMatch(items: Item[]): Item | undefined {\n for (const item of items) {\n if (matches(item)) {\n return item; // Works but not optimal for large arrays\n }\n }\n}\n```\n\n**✅ Index-based loop for early exit**\n```ts\nfunction findFirstMatch(items: Item[]): Item | undefined {\n const len = items.length;\n\n for (let i = 0; i \u003c len; i++) {\n if (matches(items[i])) {\n return items[i]; // Can exit immediately\n }\n }\n\n return undefined;\n}\n```\n\n**Why**: Built-in methods like `.find()` create function call overhead. Index-based loops are fastest for early-exit scenarios and allow fine-grained control.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":9609,"content_sha256":"23a6b3de80b9da5a3e28d1f63141b464836ec68b7955963f66b23bd73a105ae0"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"TypeScript Performance Optimization","type":"text"}]},{"type":"paragraph","content":[{"text":"Systematic performance optimization for JavaScript/TypeScript codebases. Combines audit workflow with expert-level optimization patterns for runtime performance.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"NEVER Do When Optimizing Performance","type":"text"}]},{"type":"paragraph","content":[{"text":"Note:","type":"text","marks":[{"type":"strong"}]},{"text":" For general best practices (type safety with ","type":"text"},{"text":"any","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"enum","type":"text","marks":[{"type":"code_inline"}]},{"text":", avoiding ","type":"text"},{"text":"null","type":"text","marks":[{"type":"code_inline"}]},{"text":", not mutating parameters), use the ","type":"text"},{"text":"accelint-ts-best-practices","type":"text","marks":[{"type":"code_inline"}]},{"text":" skill instead. This section focuses exclusively on performance-specific anti-patterns.","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NEVER assume code is cold path","type":"text","marks":[{"type":"strong"}]},{"text":" - Utility functions, formatters, parsers, and validators appear simple but are frequently called in loops, rendering pipelines, or real-time systems. Always audit ALL code for performance anti-patterns. Do not make assumptions about usage frequency or skip auditing based on perceived simplicity.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NEVER apply all optimizations blindly","type":"text","marks":[{"type":"strong"}]},{"text":" - Performance patterns have trade-offs. Balance optimization gains against code complexity. When conducting audits, identify ALL anti-patterns through systematic analysis and report them with expected gains. Let users decide which optimizations to apply based on their specific context.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NEVER ignore algorithmic complexity","type":"text","marks":[{"type":"strong"}]},{"text":" - Optimizing O(n²) code with micro-optimizations is futile. For n=1000, algorithmic fix (O(n² → O(n)) yields 1000x speedup; micro-optimizations yield 1.1-2x at best. Fix algorithm first: use Maps/Sets for O(1) lookups, eliminate nested iterations, choose appropriate data structures.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NEVER sacrifice correctness for speed","type":"text","marks":[{"type":"strong"}]},{"text":" - Performance bugs are still bugs. Optimizations frequently break edge cases: off-by-one errors in manual loops, wrong behavior for empty arrays, null handling issues. Verify behavior matches before and after. Add comprehensive tests covering edge cases before optimizing—catching bugs in production costs far more than any performance gain.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NEVER optimize code you don't own","type":"text","marks":[{"type":"strong"}]},{"text":" - Shared utilities, library internals, or code actively developed by others creates merge conflicts, duplicates effort, and confuses ownership. Performance changes affect all callers; coordinate with owners or defer optimization until code stabilizes.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NEVER ignore memory vs CPU trade-offs","type":"text","marks":[{"type":"strong"}]},{"text":" - Caching trades memory for speed. Unbounded memoization causes memory leaks in long-running applications. A 2x CPU speedup that increases memory 10x can trigger OOM crashes or frequent GC pauses (worse than original slowness). Profile memory usage alongside CPU; set cache size limits; use WeakMap for lifecycle-bound caches.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NEVER assume performance across environments","type":"text","marks":[{"type":"strong"}]},{"text":" - V8 optimizations differ between Node.js versions (v18 vs v20), browsers (Chrome vs Safari), and architectures (x64 vs ARM). An optimization yielding 3x speedup in Chrome may regress 1.5x in Safari. Profile in ALL target environments before shipping; maintain fallback implementations for environment-specific optimizations.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NEVER chain array methods","type":"text","marks":[{"type":"strong"}]},{"text":" (.filter().map().reduce()) - Each method creates intermediate arrays and iterates separately. For arrays with 10k items, ","type":"text"},{"text":".filter().map()","type":"text","marks":[{"type":"code_inline"}]},{"text":" allocates 10k + 5k items (if 50% pass filter) and iterates twice. Use single ","type":"text"},{"text":"reduce","type":"text","marks":[{"type":"code_inline"}]},{"text":" pass to iterate once with zero intermediate allocations, yielding 2-5x speedup in hot paths.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NEVER use ","type":"text","marks":[{"type":"strong"}]},{"text":"Array.includes()","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" for repeated lookups","type":"text","marks":[{"type":"strong"}]},{"text":" - Array.includes() is O(n) linear search. Checking 1000 items against array of 100 is O(n×m) = 100k operations. Use ","type":"text"},{"text":"Set.has()","type":"text","marks":[{"type":"code_inline"}]},{"text":" instead: O(1) lookup via hash table, reducing 100k operations to 1000 for ~100x speedup. Build Set once upfront; amortized cost is negligible.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NEVER await before checking if you need the result","type":"text","marks":[{"type":"strong"}]},{"text":" - ","type":"text"},{"text":"await","type":"text","marks":[{"type":"code_inline"}]},{"text":" suspends execution immediately, even if the value isn't needed. Move ","type":"text"},{"text":"await","type":"text","marks":[{"type":"code_inline"}]},{"text":" into conditional branches that actually use the result. Example: ","type":"text"},{"text":"const data = await fetch(url); if (condition) { use(data); }","type":"text","marks":[{"type":"code_inline"}]},{"text":" wastes I/O time when condition is false. Better: ","type":"text"},{"text":"if (condition) { const data = await fetch(url); use(data); }","type":"text","marks":[{"type":"code_inline"}]},{"text":" skips fetch entirely when unneeded.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NEVER recompute constants inside loops","type":"text","marks":[{"type":"strong"}]},{"text":" - Recomputing invariants wastes CPU in every iteration. For 10k iterations, ","type":"text"},{"text":"array.length","type":"text","marks":[{"type":"code_inline"}]},{"text":" lookup (even if cached by engine) or ","type":"text"},{"text":"Math.max(a, b)","type":"text","marks":[{"type":"code_inline"}]},{"text":" runs 10k times unnecessarily. Hoist invariants outside loops: ","type":"text"},{"text":"const len = array.length; for (let i = 0; i \u003c len; i++)","type":"text","marks":[{"type":"code_inline"}]},{"text":" or curry functions to precompute constant parameters once.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NEVER create unbounded loops or queues","type":"text","marks":[{"type":"strong"}]},{"text":" - Prevents runaway resource consumption from bugs or malicious input. Set explicit limits (","type":"text"},{"text":"for (let i = 0; i \u003c Math.min(items.length, 10000); i++)","type":"text","marks":[{"type":"code_inline"}]},{"text":") or timeouts. Unbounded loops can freeze UI threads; unbounded queues cause OOM crashes. Fail fast with clear limits rather than degrading gracefully into unusability.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NEVER place ","type":"text","marks":[{"type":"strong"}]},{"text":"try/catch","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" in hot paths","type":"text","marks":[{"type":"strong"}]},{"text":" - V8 cannot inline functions containing try-catch blocks and marks entire function as non-optimizable. Single try-catch in hot loop causes 3-5x slowdown by preventing inlining, escape analysis, and other optimizations. Validate inputs before hot paths using type guards; move try-catch outside loops to wrap entire operation; use Result types for expected errors.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Before Optimizing Performance, Ask","type":"text"}]},{"type":"paragraph","content":[{"text":"Apply these tests to focus optimization efforts effectively:","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Impact Assessment","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Is this code actually slow?","type":"text","marks":[{"type":"strong"}]},{"text":" When profiling data is available, use it to inform prioritization. When unavailable, audit all code for anti-patterns.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"What percentage of runtime does this represent?","type":"text","marks":[{"type":"strong"}]},{"text":" When profiling data is available, flame graphs help identify the highest-impact issues. When unavailable, report all anti-patterns found.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Raw performance matters","type":"text","marks":[{"type":"strong"}]},{"text":" - Audit ALL code for performance anti-patterns regardless of current usage context. Utility functions, formatters, parsers, and data transformations are frequently called in loops, rendering pipelines, or real-time systems even when they appear simple.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Correctness Verification","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Do I have tests covering this code?","type":"text","marks":[{"type":"strong"}]},{"text":" Performance bugs are subtle. Comprehensive tests catch regressions from optimizations. Add tests before optimizing.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"What are the edge cases?","type":"text","marks":[{"type":"strong"}]},{"text":" Off-by-one errors, empty arrays, null/undefined values become more likely with manual loop optimizations. Test exhaustively.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Complexity vs Benefit","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Is the algorithmic complexity optimal?","type":"text","marks":[{"type":"strong"}]},{"text":" O(n) → O(1) is 1000x speedup. Micro-optimizations are 1.1-2x at best. Fix algorithm first.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Will this optimization persist?","type":"text","marks":[{"type":"strong"}]},{"text":" If the code changes frequently, optimization may be discarded soon. Optimize stable code first.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"What's the readability cost?","type":"text","marks":[{"type":"strong"}]},{"text":" Manual loops are faster but harder to maintain than ","type":"text"},{"text":".map()","type":"text","marks":[{"type":"code_inline"}]},{"text":". Balance performance with team velocity.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"How to Use","type":"text"}]},{"type":"paragraph","content":[{"text":"This skill uses ","type":"text"},{"text":"progressive disclosure","type":"text","marks":[{"type":"strong"}]},{"text":" to minimize context usage:","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"1. Start with the Workflow (SKILL.md)","type":"text"}]},{"type":"paragraph","content":[{"text":"Follow the 4-phase audit workflow below for systematic performance analysis.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"2. Reference Performance Rules Overview (AGENTS.md)","type":"text"}]},{"type":"paragraph","content":[{"text":"Load ","type":"text"},{"text":"AGENTS.md","type":"text","marks":[{"type":"link","attrs":{"href":"AGENTS.md","title":null}}]},{"text":" to scan compressed rule summaries organized by category.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"3. Load Specific Performance Patterns as Needed","type":"text"}]},{"type":"paragraph","content":[{"text":"When you identify specific performance issues, load corresponding reference files for detailed ❌/✅ examples.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"4. Use the Report Template (For Explicit Audit Requests)","type":"text"}]},{"type":"paragraph","content":[{"text":"When users explicitly request a performance audit, load the template for consistent reporting:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"assets/output-report-template.md","type":"text","marks":[{"type":"link","attrs":{"href":"assets/output-report-template.md","title":null}}]},{"text":" - Structured template with guidance","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Performance Optimization Workflow","type":"text"}]},{"type":"paragraph","content":[{"text":"Two modes of operation:","type":"text","marks":[{"type":"strong"}]}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Audit Mode","type":"text","marks":[{"type":"strong"}]},{"text":" - Skill invoked directly (","type":"text"},{"text":"/accelint-ts-performance \u003cpath>","type":"text","marks":[{"type":"code_inline"}]},{"text":") or user explicitly requests performance audit","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Generate a structured audit report using the template (Phases 1-2 only)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Report findings for user review before implementation","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"User decides which optimizations to apply","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Implementation Mode","type":"text","marks":[{"type":"strong"}]},{"text":" - Skill triggers automatically during feature work","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identify and apply optimizations directly (all 4 phases)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No formal report needed","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Focus on fixing issues inline","type":"text"}]}]}]}]}]},{"type":"paragraph","content":[{"text":"Copy this checklist to track progress:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"- [ ] Phase 1: Profile - Identify actual bottlenecks using profiling tools\n- [ ] Phase 2: Analyze - Categorize issues by impact and optimization category\n- [ ] Phase 3: Optimize - Apply performance patterns from references/\n- [ ] Phase 4: Verify - Measure improvements and validate correctness","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Phase 1: Profile to Identify Bottlenecks","type":"text"}]},{"type":"paragraph","content":[{"text":"CRITICAL: Audit ALL code for performance anti-patterns.","type":"text","marks":[{"type":"strong"}]},{"text":" Do not skip code based on assumptions about usage frequency. Utility functions, formatters, parsers, validators, and data transformations are frequently called in loops, rendering pipelines, or real-time systems even if their implementation appears simple.","type":"text"}]},{"type":"paragraph","content":[{"text":"When profiling tools are available","type":"text","marks":[{"type":"strong"}]},{"text":", use them to establish baseline measurements:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Browser","type":"text","marks":[{"type":"strong"}]},{"text":": Chrome DevTools Performance tab","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Node.js","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"node --prof script.js && node --prof-process isolate-*.log","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"paragraph","content":[{"text":"Whether profiling data is available or not","type":"text","marks":[{"type":"strong"}]},{"text":": Perform systematic static code analysis to identify ALL performance anti-patterns:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"O(n²) complexity (nested loops, repeated searches)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Excessive allocations (template literals, object spreads, array methods)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Template literal allocation when String() would suffice","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Array method chaining (.filter().map())","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Blocking async operations","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Try/catch in loops","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Output","type":"text","marks":[{"type":"strong"}]},{"text":": Complete list of ALL identified anti-patterns with their locations and expected performance impact. Do not filter based on \"severity\" or \"priority\" - report everything found.","type":"text"}]},{"type":"paragraph","content":[{"text":"When generating audit reports","type":"text","marks":[{"type":"strong"}]},{"text":" (when skill is invoked directly via ","type":"text"},{"text":"/accelint-ts-performance \u003cpath>","type":"text","marks":[{"type":"code_inline"}]},{"text":" or user explicitly requests performance audit), use the structured template:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Load ","type":"text"},{"text":"assets/output-report-template.md","type":"text","marks":[{"type":"link","attrs":{"href":"assets/output-report-template.md","title":null}}]},{"text":" for the report structure","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Follow the template's guidance for consistent formatting and issue grouping","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Phase 2: Analyze and Categorize Issues","type":"text"}]},{"type":"paragraph","content":[{"text":"For EVERY issue identified in Phase 1, categorize by optimization type:","type":"text"}]},{"type":"paragraph","content":[{"text":"Categorize ALL issues by optimization type:","type":"text","marks":[{"type":"strong"}]}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Issue Type","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Category","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Expected Gain","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Nested loops, O(n²) complexity","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Algorithmic optimization","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"10-1000x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Repeated expensive computations","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Caching & memoization","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"2-100x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Allocation-heavy code","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Allocation reduction","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1.5-5x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Sequential access violations","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Memory locality","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1.5-3x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Excessive I/O operations","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"I/O optimization","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"5-50x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Blocking async operations","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"I/O optimization","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"2-10x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Property access in loops","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Caching & memoization","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1.2-2x","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"Quick reference for mapping issues:","type":"text","marks":[{"type":"strong"}]}]},{"type":"paragraph","content":[{"text":"Load ","type":"text"},{"text":"references/quick-reference.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/quick-reference.md","title":null}}]},{"text":" for detailed issue-to-category mapping and anti-pattern detection.","type":"text"}]},{"type":"paragraph","content":[{"text":"Output:","type":"text","marks":[{"type":"strong"}]},{"text":" Categorized list of ALL issues with their optimization categories. Do not filter or prioritize - list everything found in Phase 1.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Phase 3: Optimize Using Performance Patterns","type":"text"}]},{"type":"paragraph","content":[{"text":"Step 1: Identify your bottleneck category","type":"text","marks":[{"type":"strong"}]},{"text":" from Phase 2 analysis.","type":"text"}]},{"type":"paragraph","content":[{"text":"Step 2","type":"text","marks":[{"type":"strong"}]},{"text":": Load MANDATORY references for your category. Read each file completely with no range limits.","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Category","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"MANDATORY Files","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Optional","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Do NOT Load","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Algorithmic","type":"text","marks":[{"type":"strong"}]},{"text":" (O(n²), nested loops, repeated lookups)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"reduce-looping.md","type":"text"},{"type":"br"},{"text":"reduce-branching.md","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"—","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"memoization, caching, I/O, allocation","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Caching","type":"text","marks":[{"type":"strong"}]},{"text":" (property access in loops, repeated calculations)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"memoization.md","type":"text"},{"type":"br"},{"text":"cache-property-access.md","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"cache-storage-api.md (for Storage APIs)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"I/O, allocation","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"I/O","type":"text","marks":[{"type":"strong"}]},{"text":" (blocking async, excessive I/O operations)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"batching.md","type":"text"},{"type":"br"},{"text":"defer-await.md","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"—","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"algorithmic, memory","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Memory","type":"text","marks":[{"type":"strong"}]},{"text":" (allocation-heavy, GC pressure)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"object-operations.md","type":"text"},{"type":"br"},{"text":"avoid-allocations.md","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"—","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"I/O, caching","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Locality","type":"text","marks":[{"type":"strong"}]},{"text":" (sequential access violations, cache misses)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"predictable-execution.md","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"—","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"all others","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Safety","type":"text","marks":[{"type":"strong"}]},{"text":" (unbounded loops, runaway queues)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"bounded-iteration.md","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"—","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"all others","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Micro-opt","type":"text","marks":[{"type":"strong"}]},{"text":" (hot path fine-tuning, 1.1-2x improvements)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"currying.md","type":"text"},{"type":"br"},{"text":"performance-misc.md","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"—","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"all others (apply only after algorithmic fixes)","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"Notes","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If bottleneck spans multiple categories, load references for all relevant categories","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Only apply micro-optimizations if: bottleneck is in hot path, algorithmic optimization already applied, need additional 1.1-2x performance","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"paragraph","content":[{"text":"Step 3: Scan for quick reference during optimization","type":"text","marks":[{"type":"strong"}]}]},{"type":"paragraph","content":[{"text":"Load ","type":"text"},{"text":"AGENTS.md","type":"text","marks":[{"type":"link","attrs":{"href":"AGENTS.md","title":null}}]},{"text":" to see compressed rule summaries organized by category. Use as a quick lookup while implementing patterns from the detailed reference files above.","type":"text"}]},{"type":"paragraph","content":[{"text":"Apply patterns systematically:","type":"text","marks":[{"type":"strong"}]}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Load the reference file","type":"text","marks":[{"type":"strong"}]},{"text":" for the identified issue category","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Scan the ❌/✅ examples","type":"text","marks":[{"type":"strong"}]},{"text":" to find matching patterns","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Apply the optimization","type":"text","marks":[{"type":"strong"}]},{"text":" with minimal changes to preserve correctness","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Add comments","type":"text","marks":[{"type":"strong"}]},{"text":" explaining the optimization and referencing the pattern","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Example optimization:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"// ❌ Before: O(n²) - nested iteration\nfor (const user of users) {\n const items = allItems.filter(item => item.userId === user.id);\n process(items);\n}\n\n// ✅ After: O(n) - single pass with Map lookup\n// Performance: reduce-looping.md - build lookup once pattern\nconst itemsByUser = new Map\u003cstring, Item[]>();\nfor (const item of allItems) {\n if (!itemsByUser.has(item.userId)) {\n itemsByUser.set(item.userId, []);\n }\n itemsByUser.get(item.userId)!.push(item);\n}\n\nfor (const user of users) {\n const items = itemsByUser.get(user.id) ?? [];\n process(items);\n}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Phase 4: Verify Improvements","type":"text"}]},{"type":"paragraph","content":[{"text":"Measure performance gain:","type":"text","marks":[{"type":"strong"}]}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Re-run profiler with same inputs","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Compare before/after runtime percentages","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Document speedup factor (e.g., \"2.3x faster\")","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Verify correctness:","type":"text","marks":[{"type":"strong"}]}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Run existing test suite - all tests must pass","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Add new tests for edge cases affected by optimization","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Manual testing for user-facing functionality","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Document optimization:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"// Performance optimization applied: 2026-01-28\n// Issue: Nested iteration causing O(n²) complexity with 10k items\n// Pattern: reduce-looping.md - Map-based lookup\n// Speedup: 145x faster (5200ms → 36ms)\n// Verified: All tests pass, manual QA complete","type":"text"}]},{"type":"paragraph","content":[{"text":"Deciding whether to keep the optimization:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":">10x speedup:","type":"text","marks":[{"type":"strong"}]},{"text":" Always keep if tests pass","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"2-10x speedup:","type":"text","marks":[{"type":"strong"}]},{"text":" Keep if tests pass and code remains maintainable","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"1.2-2x speedup:","type":"text","marks":[{"type":"strong"}]},{"text":" Keep for hot paths (>1000 executions/sec) or real-time systems","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"1.05-1.2x speedup:","type":"text","marks":[{"type":"strong"}]},{"text":" Keep only if trivial change or critical rendering/animation loop","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\u003c1.05x speedup:","type":"text","marks":[{"type":"strong"}]},{"text":" Revert unless it also improves readability","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Real-time systems (60fps rendering, live data visualization):","type":"text","marks":[{"type":"strong"}]},{"text":" Even 1.05x improvements matter in critical hot paths. Use frame timing profiler to verify impact on frame budget (16.67ms for 60fps).","type":"text"}]},{"type":"paragraph","content":[{"text":"If tests fail:","type":"text","marks":[{"type":"strong"}]},{"text":" Fix the optimization or revert. Performance bugs are still bugs.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Freedom Calibration","type":"text"}]},{"type":"paragraph","content":[{"text":"Calibrate guidance specificity to optimization impact:","type":"text","marks":[{"type":"strong"}]}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Optimization Type","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Freedom Level","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Guidance Format","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Example","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Algorithmic (10x+ gain)","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Medium freedom","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Multiple valid approaches, pick based on constraints","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"Use Map for O(1) lookup or Set for deduplication\"","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Caching (2-10x gain)","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Medium freedom","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Pattern with examples, cache invalidation strategy","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"Memoize with WeakMap if lifecycle matches source objects\"","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Micro-optimization (1.1-2x)","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Low freedom","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Exact pattern from reference, measure first","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"Cache array.length in loop: ","type":"text"},{"text":"for (let i = 0, len = arr.length; ...)","type":"text","marks":[{"type":"code_inline"}]},{"text":"\"","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"The test:","type":"text","marks":[{"type":"strong"}]},{"text":" \"What's the speedup and maintenance cost?\"","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"10x+ speedup → Worth complexity, medium freedom with patterns","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"2-10x speedup → Justify with measurements, medium freedom","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"1.2-2x speedup → Valuable for hot paths and real-time systems, low freedom with exact patterns","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"1.05-1.2x speedup → Only if trivial change or critical hot path (60fps rendering, etc.)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Important Notes","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Audit everything philosophy","type":"text","marks":[{"type":"strong"}]},{"text":" - Audit ALL code for performance anti-patterns. Utility functions, formatters, parsers, and validators are frequently called in loops or real-time systems even when they appear simple. Do not make assumptions about usage frequency.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Report all findings","type":"text","marks":[{"type":"strong"}]},{"text":" - Whether profiling data is available or not, perform systematic static analysis to identify and report ALL anti-patterns with their expected gains. Do not filter based on \"severity\" or \"priority.\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Reference files are authoritative","type":"text","marks":[{"type":"strong"}]},{"text":" - The patterns in references/ have been validated. Follow them exactly unless measurements prove otherwise.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Hot path definition","type":"text","marks":[{"type":"strong"}]},{"text":" - Code executed >1000 times per user interaction or >100 times per second in server contexts. For real-time systems (60fps rendering, live visualization), hot paths are functions in the critical rendering loop consuming >1ms per frame.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Real-time systems have stricter requirements","type":"text","marks":[{"type":"strong"}]},{"text":" - 60fps = 16.67ms frame budget. 120fps = 8.33ms. Even 1.05x improvements in hot paths are valuable. Profile with frame timing, not just total execution time.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Regression testing","type":"text","marks":[{"type":"strong"}]},{"text":" - Performance optimizations frequently introduce subtle bugs in edge cases. Add tests before optimizing.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Memory profiling matters","type":"text","marks":[{"type":"strong"}]},{"text":" - Some optimizations (memoization, caching) trade memory for speed. Monitor memory usage in production, especially for long-running real-time applications.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Quick Decision Tree","type":"text"}]},{"type":"paragraph","content":[{"text":"Use this table to rapidly identify which optimization category applies.","type":"text"}]},{"type":"paragraph","content":[{"text":"Audit everything","type":"text","marks":[{"type":"strong"}]},{"text":": Identify ALL performance anti-patterns in the code regardless of current usage context. Report all findings with expected gains.","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"If You See...","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Root Cause","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Optimization Category","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Expected Gain","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Nested ","type":"text"},{"text":"for","type":"text","marks":[{"type":"code_inline"}]},{"text":" loops over same data","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"O(n²) complexity","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Algorithmic (reduce-looping)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"10-1000x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":".filter()","type":"text","marks":[{"type":"code_inline"}]},{"text":" followed by ","type":"text"},{"text":".find()","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":".map()","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Multiple passes over data","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Algorithmic (reduce-looping)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"2-10x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Repeated ","type":"text"},{"text":"array.find()","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":".includes()","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"O(n) linear search","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Algorithmic (reduce-looping, use Set/Map)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"10-100x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Many ","type":"text"},{"text":"if/else","type":"text","marks":[{"type":"code_inline"}]},{"text":" chains on same variable","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Branch-heavy code","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Algorithmic (reduce-branching)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1.5-3x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Same function called with same inputs repeatedly","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Redundant computation","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Caching (memoization)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"2-100x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"obj.prop.nested.deep","type":"text","marks":[{"type":"code_inline"}]},{"text":" accessed multiple times in loop","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Property access overhead","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Caching (cache-property-access)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1.2-2x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"localStorage.getItem()","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"sessionStorage","type":"text","marks":[{"type":"code_inline"}]},{"text":" in loop","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Expensive I/O in loop","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Caching (cache-storage-api)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"5-20x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Multiple ","type":"text"},{"text":"await fetch()","type":"text","marks":[{"type":"code_inline"}]},{"text":" in sequence","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Sequential I/O blocking","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"I/O (batching, defer-await)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"2-10x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"await","type":"text","marks":[{"type":"code_inline"}]},{"text":" before conditional that might not need result","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Premature async suspension","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"I/O (defer-await)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1.5-3x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Many object spreads ","type":"text"},{"text":"{...obj}","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"[...arr]","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Allocation overhead","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Memory (avoid-allocations)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1.5-5x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Creating objects/arrays inside hot loops","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"GC pressure from allocations","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Memory (avoid-allocations)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"2-5x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Object.assign()","type":"text","marks":[{"type":"code_inline"}]},{"text":" or spread when mutation is safe","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Unnecessary immutability cost","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Memory (object-operations)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1.5-3x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Accessing array elements non-sequentially","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Cache locality issues","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Memory Locality (predictable-execution)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1.5-3x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"while(true)","type":"text","marks":[{"type":"code_inline"}]},{"text":" or unbounded queue growth","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Runaway resource usage","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Safety (bounded-iteration)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Prevents crashes","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Function called with mostly same first N params","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Repeated parameter passing","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Micro-opt (currying)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1.1-1.5x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"try/catch","type":"text","marks":[{"type":"code_inline"}]},{"text":" inside hot loop","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"V8 deoptimization","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Micro-opt (performance-misc)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"3-5x","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"String concatenation in loop with ","type":"text"},{"text":"+","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Quadratic string copying","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Micro-opt (performance-misc)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"2-10x","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"How to use this table:","type":"text","marks":[{"type":"strong"}]}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identify the pattern from profiler bottleneck","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Find matching row in \"If You See...\" column","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Jump to corresponding Optimization Category in Phase 3","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Load MANDATORY reference files for that category","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"accelint-ts-performance","author":"@skillopedia","source":{"stars":14,"repo_name":"agent-skills","origin_url":"https://github.com/gohypergiant/agent-skills/blob/HEAD/skills/accelint-ts-performance/SKILL.md","repo_owner":"gohypergiant","body_sha256":"7105ef19f0071cf0659784c2083ab524de0a95d698d289bab0f5c12a8b9d25cc","cluster_key":"09d03e20c794c0491ed8e5aa10449ffa9047e155d96b4a7090a0935cbd0ca78d","clean_bundle":{"format":"clean-skill-bundle-v1","source":"gohypergiant/agent-skills/skills/accelint-ts-performance/SKILL.md","attachments":[{"id":"9bf79a99-bfb2-598f-baf6-7c8dc1eab61c","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/9bf79a99-bfb2-598f-baf6-7c8dc1eab61c/attachment.md","path":"AGENTS.md","size":7855,"sha256":"b06322a4c3b8d5f0672cef32e8a0fd2866489a33da100b01e380bfc2e8e7daea","contentType":"text/markdown; charset=utf-8"},{"id":"b5960623-782b-59bc-9efc-8042c2f40614","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/b5960623-782b-59bc-9efc-8042c2f40614/attachment.md","path":"README.md","size":3981,"sha256":"82cda053ea0ec503a2759ce9acaa9181e667a84a0cd88669bfab00ad27ac152c","contentType":"text/markdown; charset=utf-8"},{"id":"bf0eb163-e661-5e38-964a-705a72bf7f5a","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/bf0eb163-e661-5e38-964a-705a72bf7f5a/attachment.md","path":"assets/output-report-template.md","size":6048,"sha256":"636daf20a2decaea0b86cabefadbb15f9a19f6b2bde3532fb0f4675875a7db14","contentType":"text/markdown; charset=utf-8"},{"id":"a34b814e-4dd2-551c-9c58-b8d3880c77fb","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/a34b814e-4dd2-551c-9c58-b8d3880c77fb/attachment.md","path":"references/avoid-allocations.md","size":5447,"sha256":"5c5f9d9acc6588e1e7bc5ad1a3fee6a5e7ce427a184d41480f1801ad6b0cbc2f","contentType":"text/markdown; charset=utf-8"},{"id":"8ba36643-865e-58cb-8333-9cecad1baf82","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/8ba36643-865e-58cb-8333-9cecad1baf82/attachment.md","path":"references/batching.md","size":100,"sha256":"3449b6cade5bcc1e9c8cc05513daf0dde80d5636e31da6bc2a8a8c359ad54867","contentType":"text/markdown; charset=utf-8"},{"id":"ba654779-894b-542b-a705-3e4065c3e562","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/ba654779-894b-542b-a705-3e4065c3e562/attachment.md","path":"references/bounded-iteration.md","size":7760,"sha256":"fe340c8aad9729b06590294cd5e1208e4baee8468d98c1750a14e7d8cf206c6f","contentType":"text/markdown; charset=utf-8"},{"id":"5677cd44-e129-5f12-92f5-974ad9b315dd","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/5677cd44-e129-5f12-92f5-974ad9b315dd/attachment.md","path":"references/cache-property-access.md","size":2092,"sha256":"7caa4cf33baa561abf7d164e39e7ffe07ef387d3c47c6575f3c0d65c7da57538","contentType":"text/markdown; charset=utf-8"},{"id":"f65581f1-0429-5ab8-9143-b0a3572e1b63","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/f65581f1-0429-5ab8-9143-b0a3572e1b63/attachment.md","path":"references/cache-storage-api.md","size":1378,"sha256":"8fcf59effd48653c4db4b62663377098c8e808c3b89be00a1e008d8676c41471","contentType":"text/markdown; charset=utf-8"},{"id":"658d450f-8e77-5c23-a416-0760dbda506f","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/658d450f-8e77-5c23-a416-0760dbda506f/attachment.md","path":"references/currying.md","size":10828,"sha256":"bf369298a4e1683011cb904f616067b893656f1662c79b0799ecded85cd0ae04","contentType":"text/markdown; charset=utf-8"},{"id":"76c49dcb-02cf-57d1-91bb-6aa456b5f581","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/76c49dcb-02cf-57d1-91bb-6aa456b5f581/attachment.md","path":"references/defer-await.md","size":974,"sha256":"7bc216c75c9e076f1096e348b080d366b69a101f070b99c8c36a8433e4495766","contentType":"text/markdown; charset=utf-8"},{"id":"34953062-0fb2-5101-9846-1aae4780ed0d","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/34953062-0fb2-5101-9846-1aae4780ed0d/attachment.md","path":"references/memoization.md","size":10082,"sha256":"6759c8340dee93bab9c26532123bf623b6eef66d9827b7a8c99ca8d4af78fc3b","contentType":"text/markdown; charset=utf-8"},{"id":"04cc6cc7-9120-5b2b-9f51-7f007d560547","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/04cc6cc7-9120-5b2b-9f51-7f007d560547/attachment.md","path":"references/object-operations.md","size":2675,"sha256":"f6ae4913c185c5004f2c04ab8356cdd9616962c57194bc06900f35e0f9bba3ea","contentType":"text/markdown; charset=utf-8"},{"id":"147994b6-1c22-5481-b8e0-828be8578d98","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/147994b6-1c22-5481-b8e0-828be8578d98/attachment.md","path":"references/performance-misc.md","size":4573,"sha256":"f4f05aee4b12bc85a72a546f4a5e0224ba906393b9cfc4fbb00a19dc517b7265","contentType":"text/markdown; charset=utf-8"},{"id":"41ec655b-62f9-5f39-87a7-34bb72e7a99e","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/41ec655b-62f9-5f39-87a7-34bb72e7a99e/attachment.md","path":"references/predictable-execution.md","size":3130,"sha256":"f291d2e93bcceca97a36203d9eec3ff502a0e586cfb8b2615a05d05839b2b18d","contentType":"text/markdown; charset=utf-8"},{"id":"694832a6-eff0-5d24-a1ed-c479068ab4af","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/694832a6-eff0-5d24-a1ed-c479068ab4af/attachment.md","path":"references/quick-reference.md","size":7072,"sha256":"d6cd7d1f780dd90662f876c3000fd6ec0fc13b82974bbbb5f43d9411d436d656","contentType":"text/markdown; charset=utf-8"},{"id":"e0e92fc8-f5ee-5201-bab8-a8d85745ab85","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/e0e92fc8-f5ee-5201-bab8-a8d85745ab85/attachment.md","path":"references/reduce-branching.md","size":2083,"sha256":"179fa9774b0c5912af01598f6befe052a0b7ad5c044b5b9f11babafc22484be7","contentType":"text/markdown; charset=utf-8"},{"id":"475a05a0-d76a-5bb5-a17c-bedf3756e1ad","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/475a05a0-d76a-5bb5-a17c-bedf3756e1ad/attachment.md","path":"references/reduce-looping.md","size":9609,"sha256":"23a6b3de80b9da5a3e28d1f63141b464836ec68b7955963f66b23bd73a105ae0","contentType":"text/markdown; charset=utf-8"}],"bundle_sha256":"22509fcb4cfb72fe2ad49a5d325d909a93848bdfc002720c2e85f93ffb19d732","attachment_count":17,"text_attachments":17,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"skills/accelint-ts-performance/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"security","category_label":"Security"},"exact_dupes_collapsed_into_this":0},"license":"Apache-2.0","version":"v1","category":"security","metadata":{"author":"accelint","version":"1.1.0"},"import_tag":"clean-skills-v1","description":"Systematic JavaScript/TypeScript performance audit and optimization using V8 profiling and runtime patterns. Use when (1) Users say 'optimize performance', 'audit performance', 'this is slow', 'reduce allocations', 'improve speed', 'check performance', (2) Analyzing code for performance anti-patterns (O(n²) complexity, excessive allocations, I/O blocking, template literal waste), (3) Optimizing functions regardless of current usage context - utilities, formatters, parsers are often called in hot paths even when they appear simple, (4) Fixing V8 deoptimization (monomorphic/polymorphic issues, inline caching). Audits ALL code for anti-patterns and reports findings with expected gains. Covers loops, caching, batching, memory locality, algorithmic complexity fixes with ❌/✅ patterns."}},"renderedAt":1782980515742}

TypeScript Performance Optimization Systematic performance optimization for JavaScript/TypeScript codebases. Combines audit workflow with expert-level optimization patterns for runtime performance. NEVER Do When Optimizing Performance Note: For general best practices (type safety with / , avoiding , not mutating parameters), use the skill instead. This section focuses exclusively on performance-specific anti-patterns. - NEVER assume code is cold path - Utility functions, formatters, parsers, and validators appear simple but are frequently called in loops, rendering pipelines, or real-time sys…