Files
Claude-Code-Workflow/.claude/skills/review-code/specs/rules/performance-rules.json
catlog22 15514c8f91 Add multi-dimensional code review rules for architecture, correctness, performance, readability, security, and testing
- Introduced architecture rules to detect circular dependencies, god classes, layer violations, and mixed concerns.
- Added correctness rules focusing on null checks, empty catch blocks, unreachable code, and type coercion.
- Implemented performance rules addressing nested loops, synchronous I/O, memory leaks, and unnecessary re-renders in React.
- Created readability rules to improve function length, variable naming, deep nesting, magic numbers, and commented code.
- Established security rules to identify XSS risks, hardcoded secrets, SQL injection vulnerabilities, and insecure random generation.
- Developed testing rules to enhance test quality, coverage, and maintainability, including missing assertions and error path testing.
- Documented the structure and schema for rule files in the index.md for better understanding and usage.
2026-01-13 14:53:20 +08:00

60 lines
3.6 KiB
JSON

{
"dimension": "performance",
"prefix": "PERF",
"description": "Rules for detecting performance issues including inefficient algorithms, memory leaks, and resource waste",
"rules": [
{
"id": "nested-loops",
"category": "algorithm-complexity",
"severity": "medium",
"pattern": "for\\s*\\([^)]+\\)\\s*\\{[^}]*for\\s*\\([^)]+\\)|forEach\\s*\\([^)]+\\)\\s*\\{[^}]*forEach",
"patternType": "regex",
"description": "Nested loops may indicate O(n^2) or worse complexity. Consider if this can be optimized",
"recommendation": "Use Map/Set for O(1) lookups, break early when possible, or restructure the algorithm",
"fixExample": "// Before - O(n^2)\nfor (const a of listA) {\n for (const b of listB) {\n if (a.id === b.id) { ... }\n }\n}\n\n// After - O(n)\nconst bMap = new Map(listB.map(b => [b.id, b]));\nfor (const a of listA) {\n const b = bMap.get(a.id);\n if (b) { ... }\n}"
},
{
"id": "array-in-loop",
"category": "inefficient-operation",
"severity": "high",
"pattern": "\\.includes\\s*\\(|indexOf\\s*\\(|find\\s*\\(",
"patternType": "includes",
"contextPattern": "for|while|forEach|map|filter|reduce",
"description": "Array search methods inside loops cause O(n*m) complexity. Consider using Set or Map",
"recommendation": "Convert array to Set before the loop for O(1) lookups",
"fixExample": "// Before - O(n*m)\nfor (const item of items) {\n if (existingIds.includes(item.id)) { ... }\n}\n\n// After - O(n)\nconst idSet = new Set(existingIds);\nfor (const item of items) {\n if (idSet.has(item.id)) { ... }\n}"
},
{
"id": "synchronous-io",
"category": "io-efficiency",
"severity": "high",
"pattern": "readFileSync|writeFileSync|execSync|spawnSync",
"patternType": "includes",
"description": "Synchronous I/O blocks the event loop and degrades application responsiveness",
"recommendation": "Use async versions (readFile, writeFile) or Promise-based APIs",
"fixExample": "// Before\nconst data = fs.readFileSync(path);\n\n// After\nconst data = await fs.promises.readFile(path);\n// or\nfs.readFile(path, (err, data) => { ... });"
},
{
"id": "memory-leak-closure",
"category": "memory-leak",
"severity": "high",
"pattern": "addEventListener\\s*\\(|setInterval\\s*\\(|setTimeout\\s*\\(",
"patternType": "regex",
"negativePatterns": ["removeEventListener", "clearInterval", "clearTimeout"],
"description": "Event listeners and timers without cleanup can cause memory leaks",
"recommendation": "Always remove event listeners and clear timers in cleanup functions (componentWillUnmount, useEffect cleanup)",
"fixExample": "// Before\nuseEffect(() => {\n window.addEventListener('resize', handler);\n}, []);\n\n// After\nuseEffect(() => {\n window.addEventListener('resize', handler);\n return () => window.removeEventListener('resize', handler);\n}, []);"
},
{
"id": "unnecessary-rerender",
"category": "react-performance",
"severity": "medium",
"pattern": "useState\\s*\\(\\s*\\{|useState\\s*\\(\\s*\\[",
"patternType": "regex",
"description": "Creating new object/array references in useState can cause unnecessary re-renders",
"recommendation": "Use useMemo for computed values, useCallback for functions, or consider state management libraries",
"fixExample": "// Before - new object every render\nconst [config] = useState({ theme: 'dark' });\n\n// After - stable reference\nconst defaultConfig = useMemo(() => ({ theme: 'dark' }), []);\nconst [config] = useState(defaultConfig);"
}
]
}