Restructured project from nested workspace pattern to flat single-repo layout. This eliminates redundant nesting and consolidates all project files under version control. ## Migration Summary **Before:** ``` alex/ (workspace, not versioned) ├── chess-game/ (git repo) │ ├── js/, css/, tests/ │ └── index.html └── docs/ (planning, not versioned) ``` **After:** ``` alex/ (git repo, everything versioned) ├── js/, css/, tests/ ├── index.html ├── docs/ (project documentation) ├── planning/ (historical planning docs) ├── .gitea/ (CI/CD) └── CLAUDE.md (configuration) ``` ## Changes Made ### Structure Consolidation - Moved all chess-game/ contents to root level - Removed redundant chess-game/ subdirectory - Flattened directory structure (eliminated one nesting level) ### Documentation Organization - Moved chess-game/docs/ → docs/ (project documentation) - Moved alex/docs/ → planning/ (historical planning documents) - Added CLAUDE.md (workspace configuration) - Added IMPLEMENTATION_PROMPT.md (original project prompt) ### Version Control Improvements - All project files now under version control - Planning documents preserved in planning/ folder - Merged .gitignore files (workspace + project) - Added .claude/ agent configurations ### File Updates - Updated .gitignore to include both workspace and project excludes - Moved README.md to root level - All import paths remain functional (relative paths unchanged) ## Benefits ✅ **Simpler Structure** - One level of nesting removed ✅ **Complete Versioning** - All documentation now in git ✅ **Standard Layout** - Matches open-source project conventions ✅ **Easier Navigation** - Direct access to all project files ✅ **CI/CD Compatible** - All workflows still functional ## Technical Validation - ✅ Node.js environment verified - ✅ Dependencies installed successfully - ✅ Dev server starts and responds - ✅ All core files present and accessible - ✅ Git repository functional ## Files Preserved **Implementation Files:** - js/ (3,517 lines of code) - css/ (4 stylesheets) - tests/ (87 test cases) - index.html - package.json **CI/CD Pipeline:** - .gitea/workflows/ci.yml - .gitea/workflows/release.yml **Documentation:** - docs/ (12+ documentation files) - planning/ (historical planning materials) - README.md **Configuration:** - jest.config.js, babel.config.cjs, playwright.config.js - .gitignore (merged) - CLAUDE.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
17 KiB
Performance Analysis: HTML Chess Game
Executive Summary
Performance Target: 60fps UI, <500ms AI responses, <2s page load Critical Bottlenecks: Minimax search, DOM updates, mobile rendering Optimization Potential: 10-100x improvement with proper techniques Performance Budget: 15-20 hours optimization effort
1. Performance Requirements
User Experience Targets
| Metric | Target | Good | Acceptable | Poor |
|---|---|---|---|---|
| First Contentful Paint | <500ms | <1s | <2s | >2s |
| Time to Interactive | <1s | <2s | <3s | >3s |
| Frame Rate (animations) | 60fps | 50fps | 30fps | <30fps |
| AI Response (Beginner) | <200ms | <500ms | <1s | >1s |
| AI Response (Intermediate) | <500ms | <1s | <2s | >2s |
| AI Response (Advanced) | <1s | <2s | <5s | >5s |
| Move Validation | <10ms | <50ms | <100ms | >100ms |
| Board Rendering | <16ms | <50ms | <100ms | >100ms |
| Memory Usage | <50MB | <100MB | <200MB | >200MB |
| Bundle Size | <100KB | <300KB | <500KB | >500KB |
Device Performance Targets
| Device Class | Min Frame Rate | Max AI Time | Bundle Size |
|---|---|---|---|
| Desktop (Modern) | 60fps | 2s | 500KB |
| Desktop (Old) | 30fps | 5s | 300KB |
| Mobile (High-end) | 60fps | 3s | 200KB |
| Mobile (Mid-range) | 45fps | 5s | 150KB |
| Mobile (Low-end) | 30fps | 8s | 100KB |
2. Performance Bottleneck Analysis
2.1 CRITICAL: Minimax Algorithm
Impact: 95% of computational cost | Severity: CRITICAL
Problem Analysis:
Branching Factor:
- Average chess position: ~35 legal moves
- Search depth 6: 35^6 = 1.8 billion positions
- Naive minimax: 3-5 minutes computation time
- User expectation: < 2 seconds
Complexity:
Time Complexity: O(b^d)
- b = branching factor (~35)
- d = search depth (4-8)
Depth 4: 35^4 = 1,500,625 nodes (~0.5s)
Depth 5: 35^5 = 52,521,875 nodes (~5s)
Depth 6: 35^6 = 1,838,265,625 nodes (~3min)
Depth 7: 35^7 = 64,339,296,875 nodes (~2hrs)
Optimization Strategies:
1. Alpha-Beta Pruning (CRITICAL - 90% improvement)
- Reduces nodes by 50-95%
- Best case: O(b^(d/2)) instead of O(b^d)
- Depth 6: From 1.8B to 60K-18M nodes
- Implementation effort: 8-10 hours
- Expected speedup: 10-100x
2. Move Ordering (HIGH - 50% additional improvement)
- Evaluate captures first (MVV/LVA)
- Check-giving moves next
- Killer move heuristic
- Hash move from transposition table
- Implementation effort: 5-6 hours
- Expected speedup: 2-3x on top of alpha-beta
3. Transposition Tables (HIGH - 30-50% improvement)
- Cache evaluated positions
- Same position, different move order
- ~10-20% positions are transpositions
- Memory: 10-50MB table
- Implementation effort: 8-10 hours
- Expected speedup: 1.5-2x
4. Iterative Deepening (MEDIUM - Better UX)
- Search depth 1, then 2, then 3, etc.
- Can stop anytime (time-based)
- Move ordering improves each iteration
- Only 10-15% overhead
- Implementation effort: 4-5 hours
- Benefit: Responsive AI (can stop early)
5. Quiescence Search (MEDIUM - Better play quality)
- Continue searching captures/checks
- Avoid horizon effect
- Adds 20-30% to search time
- Implementation effort: 6-8 hours
- Benefit: Stronger AI, not faster
6. Web Workers (CRITICAL - Prevents UI blocking)
- Move computation to separate thread
- Main thread stays responsive
- Message passing overhead: ~5ms
- Implementation effort: 6-8 hours
- Benefit: 60fps maintained during AI thinking
Performance Projections:
| Configuration | Nodes Evaluated | Time (Desktop) | Time (Mobile) |
|---|---|---|---|
| Naive Minimax (d=6) | 1.8B | 180s | 900s |
| + Alpha-Beta | 18M | 2s | 10s |
| + Move Ordering | 5M | 0.5s | 2.5s |
| + Transposition Table | 3M | 0.3s | 1.5s |
| + Iterative Deepening | 3.5M | 0.35s | 1.75s |
| Final (d=6) | 3-5M | 0.3-0.5s | 1.5-2.5s |
Recommendation: Implement alpha-beta + move ordering + Web Workers as mandatory, transposition tables as high priority.
2.2 HIGH: DOM Rendering Performance
Impact: 20-30ms per move | Severity: HIGH
Problem Analysis:
Current Approach (Naive):
// Re-render entire board on every move
function renderBoard() {
boardElement.innerHTML = ''; // SLOW: Forces reflow
for (let square of squares) {
const div = createElement('div'); // 64 elements created
boardElement.appendChild(div); // 64 DOM insertions
}
}
Performance Issues:
- 64 DOM elements created per render
- 64 appendChild calls (triggers 64 reflows)
- innerHTML = '' forces full layout recalculation
- 20-50ms on desktop, 50-150ms on mobile
Optimization Strategies:
1. Virtual DOM / Diffing (HIGH - 5-10x improvement)
// Only update changed squares
function updateBoard(oldBoard, newBoard) {
for (let i = 0; i < 64; i++) {
if (oldBoard[i] !== newBoard[i]) {
updateSquare(i, newBoard[i]); // Only 1-2 updates per move
}
}
}
- Effort: 6-8 hours
- Speedup: 5-10x (from 30ms to 3-5ms)
2. CSS Classes over Inline Styles (MEDIUM - 2x improvement)
// SLOW: Inline styles trigger recalculation
element.style.backgroundColor = 'red';
element.style.color = 'white';
// FAST: Single class toggle
element.classList.add('highlighted');
- Effort: 2-3 hours
- Speedup: 2x
3. DocumentFragment for Batch Updates (MEDIUM - 3x improvement)
// SLOW: 64 reflows
for (let piece of pieces) {
board.appendChild(piece);
}
// FAST: 1 reflow
const fragment = document.createDocumentFragment();
for (let piece of pieces) {
fragment.appendChild(piece);
}
board.appendChild(fragment);
- Effort: 1-2 hours
- Speedup: 3x
4. CSS Transforms for Animations (CRITICAL - 10x improvement)
// SLOW: Triggers layout
element.style.top = '100px';
element.style.left = '200px';
// FAST: GPU accelerated
element.style.transform = 'translate(200px, 100px)';
- Effort: 4-5 hours
- Speedup: 10x (60fps vs 20fps)
5. RequestAnimationFrame (MEDIUM - Smooth animations)
function animatePiece(from, to) {
requestAnimationFrame(() => {
// Update transform
requestAnimationFrame(() => {
// Trigger CSS transition
});
});
}
- Effort: 3-4 hours
- Benefit: Consistent 60fps
Performance Projections:
| Optimization | Desktop (ms) | Mobile (ms) | Frame Rate |
|---|---|---|---|
| Naive (innerHTML) | 30-50 | 100-200 | 20fps |
| + Diffing | 5-10 | 20-40 | 50fps |
| + CSS Classes | 3-6 | 10-20 | 55fps |
| + DocumentFragment | 2-4 | 8-15 | 58fps |
| + CSS Transforms | <2 | 5-10 | 60fps |
| Final | <2ms | 5-10ms | 60fps |
Recommendation: Implement diffing + CSS transforms as mandatory.
2.3 MEDIUM: Position Evaluation Function
Impact: 5-10% of AI time | Severity: MEDIUM
Problem Analysis:
Evaluation Components:
function evaluate(position) {
let score = 0;
score += materialScore(position); // 30% of time
score += positionScore(position); // 40% of time
score += kingSafety(position); // 15% of time
score += mobilityScore(position); // 15% of time
return score;
}
Complexity:
- Material: O(n) - iterate over pieces
- Positional: O(64) - piece-square tables
- King safety: O(n²) - check attackers
- Mobility: O(n²) - count legal moves
Optimization Strategies:
1. Incremental Updates (HIGH - 5x improvement)
// SLOW: Recalculate full evaluation
function evaluate(position) {
return fullEvaluation(position); // O(n²)
}
// FAST: Update only changed values
function makeMove(move) {
updateMaterialDelta(move); // O(1)
updatePositionalDelta(move); // O(1)
updateKingSafetyDelta(move); // O(n)
}
- Effort: 10-12 hours
- Speedup: 5x
2. Piece-Square Table Lookup (MEDIUM - 2x improvement)
// Pre-computed tables
const PAWN_TABLE = [
[0, 0, 0, 0, 0, 0, 0, 0],
[5, 10, 10,-20,-20, 10, 10, 5],
// ... pre-computed values
];
// O(1) lookup instead of computation
const score = PAWN_TABLE[rank][file];
- Effort: 4-5 hours
- Speedup: 2x
3. Lazy Evaluation (LOW - 10% improvement)
- Only evaluate if needed (not in transposition table)
- Skip evaluation for early cutoffs
- Effort: 2-3 hours
- Speedup: 1.1x
Performance Projections:
| Optimization | Evaluations/sec | Impact on AI |
|---|---|---|
| Naive | 50,000 | Baseline |
| + Incremental | 250,000 | 1.5x faster AI |
| + Piece-Square Tables | 500,000 | 1.8x faster AI |
| + Lazy Evaluation | 550,000 | 1.9x faster AI |
Recommendation: Implement incremental updates for endgame, piece-square tables for all phases.
2.4 MEDIUM: Memory Usage
Impact: Mobile performance | Severity: MEDIUM
Problem Analysis:
Memory Consumers:
- Game state: ~5KB (board + metadata)
- Move history: ~1KB per move (50KB for 50 moves)
- Transposition table: 10-50MB (configurable)
- UI event listeners: ~1KB
- Animation frames: ~5KB
- Total: 15-100MB depending on transposition table
Mobile Constraints:
- Low-end Android: 512MB RAM total
- Browser limit: ~100-200MB per tab
- Garbage collection pauses: 10-50ms
Optimization Strategies:
1. Transposition Table Size Limits (HIGH)
// Desktop: 50MB table
// Mobile: 10MB table
const maxTableSize = isMobile() ? 10_000_000 : 50_000_000;
- Effort: 2-3 hours
- Benefit: Prevents crashes on mobile
2. Object Pooling (MEDIUM - Reduces GC pauses)
// SLOW: Creates 100,000 objects during search
function generateMoves() {
return moves.map(m => ({ from, to, piece }));
}
// FAST: Reuse pre-allocated objects
const movePool = createPool(1000);
function generateMoves() {
return moves.map(m => movePool.acquire().set(from, to, piece));
}
- Effort: 8-10 hours
- Speedup: 20-30% (reduces GC pauses)
3. Move History Truncation (LOW)
- Keep only last 50 moves in memory
- Store older moves in compressed format
- Effort: 3-4 hours
- Benefit: Prevents memory growth in long games
Memory Projections:
| Configuration | Desktop | Mobile | GC Frequency |
|---|---|---|---|
| Naive | 100MB | 80MB | Every 5s |
| + Table Limits | 50MB | 15MB | Every 10s |
| + Object Pooling | 40MB | 12MB | Every 20s |
| + History Truncation | 35MB | 10MB | Every 30s |
Recommendation: Implement all three for mobile support.
3. Page Load Performance
3.1 Bundle Size Optimization
Current Analysis:
| Asset | Unoptimized | Optimized | Compression |
|---|---|---|---|
| HTML | 5KB | 3KB | Minify |
| CSS | 15KB | 8KB | Minify + purge |
| JavaScript | 150KB | 60KB | Minify + tree-shake |
| Piece Images (SVG) | 30KB | 20KB | SVGO |
| Sounds (optional) | 50KB | 20KB | Compress |
| Total | 250KB | 111KB | Gzip: 40KB |
Optimization Strategies:
1. Code Splitting (HIGH)
// Load AI engine only when needed
const loadAI = () => import('./ai-engine.js'); // 40KB
- Effort: 4-5 hours
- Initial load: 70KB → 30KB
2. SVG Sprites (MEDIUM)
<!-- Instead of 6 separate files -->
<svg><use href="#piece-king-white"></svg>
- Effort: 2-3 hours
- Savings: 30KB → 15KB
3. Lazy Load Sounds (LOW)
// Load on first interaction
document.addEventListener('click', loadSounds, { once: true });
- Effort: 1 hour
- Initial load: -50KB
4. Tree Shaking (MEDIUM)
- Remove unused code
- Use ES6 modules
- Effort: 3-4 hours
- Savings: 20-30%
Bundle Size Targets:
| Target | Bundle Size | Load Time (3G) | Load Time (4G) |
|---|---|---|---|
| Initial | 30KB | 1.5s | 0.5s |
| With AI | 70KB | 3.5s | 1.2s |
| Full App | 111KB | 5.5s | 1.8s |
| Gzipped | 40KB | 2s | 0.7s |
3.2 Critical Rendering Path
Optimization Strategies:
1. Inline Critical CSS (HIGH)
<style>
/* Only board layout CSS - 2KB */
.board { display: grid; grid-template-columns: repeat(8, 1fr); }
</style>
<link rel="preload" href="styles.css" as="style" onload="this.rel='stylesheet'">
- Effort: 2-3 hours
- FCP: 500ms → 200ms
2. Defer Non-Critical JavaScript (HIGH)
<script src="game.js" defer></script>
<script src="ai.js" defer></script>
- Effort: 1 hour
- TTI: 2s → 1s
3. Preconnect to CDNs (LOW)
<link rel="preconnect" href="https://fonts.googleapis.com">
- Effort: 0.5 hours
- DNS lookup saved: 100-200ms
4. Mobile Performance Optimization
Device-Specific Strategies:
Low-End Devices (<2 cores, <2GB RAM):
- Limit AI to depth 4
- Disable animations
- Reduce transposition table to 5MB
- No Web Workers (overhead too high)
- Expected: 30fps, 5s AI time
Mid-Range Devices (4 cores, 2-4GB RAM):
- AI depth 5
- Simplified animations
- 10MB transposition table
- Use Web Workers
- Expected: 45fps, 2s AI time
High-End Devices (8+ cores, 6+ GB RAM):
- AI depth 6
- Full animations
- 20MB transposition table
- Use Web Workers
- Expected: 60fps, 1s AI time
Device Detection:
function getDeviceClass() {
const cores = navigator.hardwareConcurrency || 2;
const memory = navigator.deviceMemory || 2;
if (cores >= 8 && memory >= 6) return 'high-end';
if (cores >= 4 && memory >= 2) return 'mid-range';
return 'low-end';
}
5. Benchmarking & Monitoring
Performance Metrics to Track:
Development Metrics:
- Minimax nodes per second
- Move validation time
- Rendering frame rate
- Memory usage over time
- Bundle size after each build
Production Metrics:
- First Contentful Paint (FCP)
- Largest Contentful Paint (LCP)
- Time to Interactive (TTI)
- Cumulative Layout Shift (CLS)
- AI response time (p50, p95, p99)
Benchmarking Tools:
// Performance measurement
performance.mark('ai-start');
const move = calculateBestMove(position);
performance.mark('ai-end');
performance.measure('ai-calculation', 'ai-start', 'ai-end');
// Log metrics
const measure = performance.getEntriesByName('ai-calculation')[0];
console.log(`AI took ${measure.duration}ms`);
Performance Budget:
const PERFORMANCE_BUDGET = {
'FCP': 500, // ms
'LCP': 1000, // ms
'TTI': 2000, // ms
'aiResponse': 1000, // ms
'moveValidation': 10, // ms
'rendering': 16, // ms (60fps)
'bundleSize': 100 // KB
};
6. Optimization Priority Matrix
Must Have (Critical):
- Alpha-Beta Pruning (8-10 hrs) - 10-100x AI speedup
- Web Workers (6-8 hrs) - Prevents UI blocking
- DOM Diffing (6-8 hrs) - 5-10x render speedup
- CSS Transforms (4-5 hrs) - 60fps animations
- Code Splitting (4-5 hrs) - 2x faster initial load
Total: 28-36 hours Impact: 10-100x overall performance improvement
Should Have (High Priority):
- Move Ordering (5-6 hrs) - 2-3x AI speedup
- Transposition Tables (8-10 hrs) - 1.5-2x AI speedup
- Bundle Optimization (8-10 hrs) - 50% smaller bundle
- Incremental Evaluation (10-12 hrs) - 1.5x AI speedup
- Mobile Optimization (10-12 hrs) - Supports 80% of users
Total: 41-50 hours Impact: Additional 3-5x performance improvement
Nice to Have (Medium Priority):
- Iterative Deepening (4-5 hrs) - Better UX
- Object Pooling (8-10 hrs) - Reduced GC pauses
- SVG Optimization (2-3 hrs) - 50% smaller images
Total: 14-18 hours Impact: Polish and edge case improvements
7. Performance Roadmap
Phase 1: Core Optimization (2 weeks)
- Alpha-beta pruning
- Web Workers
- DOM diffing
- CSS transforms
- Expected: 60fps, 1s AI (depth 5)
Phase 2: Advanced Optimization (2 weeks)
- Move ordering
- Transposition tables
- Bundle optimization
- Mobile support
- Expected: 60fps, 0.5s AI (depth 6)
Phase 3: Polish (1 week)
- Iterative deepening
- Object pooling
- Performance monitoring
- Expected: Production-ready performance
8. Performance Testing Plan
Automated Benchmarks:
describe('Performance', () => {
it('should calculate moves in < 1s', () => {
const start = performance.now();
const move = ai.calculateMove(position, depth: 6);
const duration = performance.now() - start;
expect(duration).toBeLessThan(1000);
});
it('should maintain 60fps during animations', () => {
const frameRates = measureFrameRate(animateMove);
expect(Math.min(...frameRates)).toBeGreaterThan(58);
});
});
Manual Testing:
- Test on 5+ device types
- Measure with Chrome DevTools Performance tab
- Lighthouse score > 90
- WebPageTest performance grade A
Conclusion
The HTML chess game has significant performance challenges, primarily:
- AI calculation (exponential complexity)
- DOM rendering (60fps requirement)
- Mobile constraints (limited resources)
With optimization, performance can improve by 10-100x:
- Naive: 180s AI time, 20fps rendering
- Optimized: 0.5s AI time, 60fps rendering
Critical optimizations (28-36 hours):
- Alpha-beta pruning
- Web Workers
- DOM diffing
- CSS transforms
- Code splitting
Expected result: Smooth 60fps gameplay with <1s AI responses on desktop, <2s on mobile.
Performance is achievable with proper techniques, but must not be afterthought - build optimization in from start.