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

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):

  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):

  1. Move Ordering (5-6 hrs) - 2-3x AI speedup
  2. Transposition Tables (8-10 hrs) - 1.5-2x AI speedup
  3. Bundle Optimization (8-10 hrs) - 50% smaller bundle
  4. Incremental Evaluation (10-12 hrs) - 1.5x AI speedup
  5. Mobile Optimization (10-12 hrs) - Supports 80% of users

Total: 41-50 hours Impact: Additional 3-5x performance improvement

Nice to Have (Medium Priority):

  1. Iterative Deepening (4-5 hrs) - Better UX
  2. Object Pooling (8-10 hrs) - Reduced GC pauses
  3. 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:

  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.