chess/docs/analysis/performance-analysis.md
Christoph Wagner 5ad0700b41 refactor: Consolidate repository structure - flatten from workspace pattern
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>
2025-11-23 10:05:26 +01:00

658 lines
17 KiB
Markdown

# 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)**:
```javascript
// 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)
```javascript
// 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)
```javascript
// 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)
```javascript
// 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)
```javascript
// 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)
```javascript
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**:
```javascript
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)
```javascript
// 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)
```javascript
// 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)
```javascript
// 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)
```javascript
// 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)
```javascript
// 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)
```html
<!-- Instead of 6 separate files -->
<svg><use href="#piece-king-white"></svg>
```
- Effort: 2-3 hours
- Savings: 30KB 15KB
**3. Lazy Load Sounds** (LOW)
```javascript
// 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)
```html
<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)
```html
<script src="game.js" defer></script>
<script src="ai.js" defer></script>
```
- Effort: 1 hour
- TTI: 2s 1s
**3. Preconnect to CDNs** (LOW)
```html
<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:
```javascript
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:
```javascript
// 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:
```javascript
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):
1. **Alpha-Beta Pruning** (8-10 hrs) - 10-100x AI speedup
2. **Web Workers** (6-8 hrs) - Prevents UI blocking
3. **DOM Diffing** (6-8 hrs) - 5-10x render speedup
4. **CSS Transforms** (4-5 hrs) - 60fps animations
5. **Code Splitting** (4-5 hrs) - 2x faster initial load
**Total**: 28-36 hours
**Impact**: 10-100x overall performance improvement
### Should Have (High Priority):
6. **Move Ordering** (5-6 hrs) - 2-3x AI speedup
7. **Transposition Tables** (8-10 hrs) - 1.5-2x AI speedup
8. **Bundle Optimization** (8-10 hrs) - 50% smaller bundle
9. **Incremental Evaluation** (10-12 hrs) - 1.5x AI speedup
10. **Mobile Optimization** (10-12 hrs) - Supports 80% of users
**Total**: 41-50 hours
**Impact**: Additional 3-5x performance improvement
### Nice to Have (Medium Priority):
11. **Iterative Deepening** (4-5 hrs) - Better UX
12. **Object Pooling** (8-10 hrs) - Reduced GC pauses
13. **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:
```javascript
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:
1. AI calculation (exponential complexity)
2. DOM rendering (60fps requirement)
3. 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.