# Performance Documentation

## Overview
This document outlines performance optimization strategies, benchmarking methodologies, and monitoring techniques for Pluro Accessibility Copilot.

## Performance Targets

### Response Time Targets
- **Document Scan**: < 2 seconds for files < 1000 lines
- **Workspace Scan**: < 30 seconds for projects < 100 files
- **Quick Fix Application**: < 500ms
- **UI Rendering**: < 100ms

### Memory Usage Targets
- **Peak Memory**: < 200MB for large files
- **Memory Leaks**: Zero tolerance
- **Garbage Collection**: < 50ms pause time

### CPU Usage Targets
- **Background Processing**: < 10% CPU
- **Active Scanning**: < 50% CPU
- **Idle State**: < 1% CPU

## Performance Optimization Strategies

### 1. Caching Strategy

#### File Content Caching
```typescript
class ContentCache {
  private cache = new Map<string, { content: string; timestamp: number }>();
  private readonly TTL = 15 * 60 * 1000; // 15 minutes (increased from 5 minutes)

  get(filePath: string): string | null {
    const cached = this.cache.get(filePath);
    if (cached && Date.now() - cached.timestamp < this.TTL) {
      return cached.content;
    }
    return null;
  }

  set(filePath: string, content: string): void {
    this.cache.set(filePath, { content, timestamp: Date.now() });
  }

  clear(): void {
    this.cache.clear();
  }
}
```

#### Rule Cache
```typescript
class RuleCache {
  private static instance: RuleCache;
  private cache = new Map<string, RuleWithStatus>();

  static getInstance(): RuleCache {
    if (!RuleCache.instance) {
      RuleCache.instance = new RuleCache();
    }
    return RuleCache.instance;
  }

  getRule(id: string): RuleWithStatus | null {
    return this.cache.get(id) || null;
  }

  setRule(id: string, rule: RuleWithStatus): void {
    this.cache.set(id, rule);
  }
}
```

### 2. Memory Management

#### Smart Memory Monitoring
The system now includes intelligent memory monitoring with the following improvements:

- **Reduced Alert Frequency**: Memory checks every 5 minutes instead of 30 seconds
- **Higher Threshold**: 90% memory usage threshold (increased from 80%)
- **Non-Modal Alerts**: Memory warnings no longer block the interface
- **Alert Cooldown**: 15-minute cooldown between alerts
- **Session Limits**: Maximum 3 alerts per session
- **User Control**: Ability to manage alerts via `pluro.manageMemoryAlerts`

#### Cache Optimization
- **Increased Cache Size**: 200 files (up from 100)
- **Extended TTL**: 15 minutes (up from 5 minutes)
- **Less Aggressive Cleanup**: 15% removal instead of 20%
- **Longer Cleanup Intervals**: 30 minutes (up from 10 minutes)

### 3. Lazy Loading

#### Dynamic Rule Loading
```typescript
class LazyRuleLoader {
  private loadedRules = new Set<string>();

  async loadRuleIfNeeded(ruleId: string): Promise<RuleWithStatus> {
    if (this.loadedRules.has(ruleId)) {
      return this.getCachedRule(ruleId);
    }

    const rule = await this.loadRuleFromSource(ruleId);
    this.loadedRules.add(ruleId);
    return rule;
  }
}
```

#### Component Lazy Loading
```typescript
// Lazy load heavy components
const HeavyComponent = lazy(() => import('./HeavyComponent'));

// Use Suspense for loading states
<Suspense fallback={<LoadingSpinner />}>
  <HeavyComponent />
</Suspense>
```

### 4. Parallel Processing

#### Concurrent Scanning
```typescript
class ParallelScanner {
  async scanWorkspace(files: string[]): Promise<AccessibilityIssue[]> {
    const chunks = this.chunkArray(files, 5); // Process 5 files at a time
    const results = await Promise.all(
      chunks.map(chunk => this.scanFileChunk(chunk))
    );
    return results.flat();
  }

  private chunkArray<T>(array: T[], size: number): T[][] {
    const chunks: T[][] = [];
    for (let i = 0; i < array.length; i += size) {
      chunks.push(array.slice(i, i + size));
    }
    return chunks;
  }
}
```

#### Worker Threads
```typescript
// Use worker threads for CPU-intensive tasks
import { Worker } from 'worker_threads';

class WorkerManager {
  private workers: Worker[] = [];

  async processWithWorker(data: any): Promise<any> {
    return new Promise((resolve, reject) => {
      const worker = new Worker('./worker.js', {
        workerData: data
      });

      worker.on('message', resolve);
      worker.on('error', reject);
      worker.on('exit', (code) => {
        if (code !== 0) {
          reject(new Error(`Worker stopped with exit code ${code}`));
        }
      });
    });
  }
}
```

### 5. Memory Management

#### Object Pooling
```typescript
class ObjectPool<T> {
  private pool: T[] = [];
  private factory: () => T;
  private reset: (obj: T) => void;

  constructor(factory: () => T, reset: (obj: T) => void) {
    this.factory = factory;
    this.reset = reset;
  }

  acquire(): T {
    return this.pool.pop() || this.factory();
  }

  release(obj: T): void {
    this.reset(obj);
    this.pool.push(obj);
  }
}
```

#### Memory Monitoring
```typescript
class MemoryMonitor {
  private static instance: MemoryMonitor;
  private memoryUsage: NodeJS.MemoryUsage[] = [];

  static getInstance(): MemoryMonitor {
    if (!MemoryMonitor.instance) {
      MemoryMonitor.instance = new MemoryMonitor();
    }
    return MemoryMonitor.instance;
  }

  recordUsage(): void {
    this.memoryUsage.push(process.memoryUsage());
    
    // Keep only last 100 records
    if (this.memoryUsage.length > 100) {
      this.memoryUsage.shift();
    }
  }

  getAverageUsage(): NodeJS.MemoryUsage {
    const sum = this.memoryUsage.reduce((acc, usage) => ({
      rss: acc.rss + usage.rss,
      heapTotal: acc.heapTotal + usage.heapTotal,
      heapUsed: acc.heapUsed + usage.heapUsed,
      external: acc.external + usage.external
    }));

    const count = this.memoryUsage.length;
    return {
      rss: sum.rss / count,
      heapTotal: sum.heapTotal / count,
      heapUsed: sum.heapUsed / count,
      external: sum.external / count
    };
  }
}
```

## Performance Benchmarking

### 1. Benchmark Suite

#### Scanner Performance
```typescript
describe('Scanner Performance', () => {
  test('should scan large file within time limit', async () => {
    const largeFile = generateLargeFile(10000); // 10k lines
    const startTime = Date.now();
    
    const issues = await scanner.scanDocument(largeFile);
    
    const duration = Date.now() - startTime;
    expect(duration).toBeLessThan(5000); // 5 seconds
    expect(issues.length).toBeGreaterThan(0);
  });

  test('should handle memory efficiently', async () => {
    const initialMemory = process.memoryUsage().heapUsed;
    
    for (let i = 0; i < 10; i++) {
      await scanner.scanDocument(generateTestFile());
    }
    
    const finalMemory = process.memoryUsage().heapUsed;
    const memoryIncrease = finalMemory - initialMemory;
    
    expect(memoryIncrease).toBeLessThan(50 * 1024 * 1024); // 50MB
  });
});
```

#### UI Performance
```typescript
describe('UI Performance', () => {
  test('should render results panel quickly', async () => {
    const issues = generateTestIssues(100);
    const startTime = performance.now();
    
    const panel = await renderResultsPanel(issues);
    
    const duration = performance.now() - startTime;
    expect(duration).toBeLessThan(100); // 100ms
  });
});
```

### 2. Load Testing

#### Concurrent User Simulation
```typescript
import { chromium } from 'playwright';

class LoadTester {
  async simulateConcurrentUsers(userCount: number): Promise<void> {
    const browsers = await Promise.all(
      Array(userCount).fill(0).map(() => chromium.launch())
    );

    const startTime = Date.now();
    
    await Promise.all(
      browsers.map(async (browser) => {
        const page = await browser.newPage();
        await page.goto('vscode://file/test.html');
        await page.waitForSelector('.accessibility-panel');
        await browser.close();
      })
    );

    const duration = Date.now() - startTime;
    console.log(`Processed ${userCount} users in ${duration}ms`);
  }
}
```

### 3. Performance Monitoring

#### Real-time Metrics
```typescript
class PerformanceMonitor {
  private metrics: Map<string, number[]> = new Map();

  recordMetric(name: string, value: number): void {
    if (!this.metrics.has(name)) {
      this.metrics.set(name, []);
    }
    this.metrics.get(name)!.push(value);
  }

  getAverageMetric(name: string): number {
    const values = this.metrics.get(name) || [];
    return values.reduce((sum, val) => sum + val, 0) / values.length;
  }

  getPercentileMetric(name: string, percentile: number): number {
    const values = this.metrics.get(name) || [];
    const sorted = values.sort((a, b) => a - b);
    const index = Math.floor((percentile / 100) * sorted.length);
    return sorted[index] || 0;
  }
}
```

## Optimization Techniques

### 1. Algorithm Optimization

#### Efficient Issue Detection
```typescript
class OptimizedScanner {
  // Use Set for O(1) lookups instead of Array.includes()
  private issueTypes = new Set(['missing-alt', 'low-contrast', 'empty-button']);

  // Use Map for O(1) attribute lookups
  private parseAttributes(element: string): Map<string, string> {
    const attributes = new Map<string, string>();
    const matches = element.matchAll(/(\w+)=["']([^"']*)["']/g);
    
    for (const match of matches) {
      attributes.set(match[1], match[2]);
    }
    
    return attributes;
  }
}
```

#### Batch Processing
```typescript
class BatchProcessor {
  private batchSize = 100;
  private queue: (() => Promise<void>)[] = [];

  async addTask(task: () => Promise<void>): Promise<void> {
    this.queue.push(task);
    
    if (this.queue.length >= this.batchSize) {
      await this.processBatch();
    }
  }

  private async processBatch(): Promise<void> {
    const batch = this.queue.splice(0, this.batchSize);
    await Promise.all(batch.map(task => task()));
  }
}
```

### 2. Data Structure Optimization

#### Efficient Issue Storage
```typescript
interface OptimizedIssue {
  readonly type: string; // Use string instead of enum for smaller memory footprint
  readonly severity: 'error' | 'warning' | 'info';
  readonly range: { start: number; end: number }; // Use numbers instead of Position objects
  readonly message: string;
  readonly fixable: boolean;
}

class IssueStore {
  private issues = new Map<string, OptimizedIssue[]>();

  addIssue(filePath: string, issue: OptimizedIssue): void {
    if (!this.issues.has(filePath)) {
      this.issues.set(filePath, []);
    }
    this.issues.get(filePath)!.push(issue);
  }

  getIssues(filePath: string): OptimizedIssue[] {
    return this.issues.get(filePath) || [];
  }
}
```

### 3. Network Optimization

#### Request Batching
```typescript
class BatchedAPIClient {
  private batchQueue: any[] = [];
  private batchTimeout: NodeJS.Timeout | null = null;

  async sendRequest(data: any): Promise<any> {
    this.batchQueue.push(data);
    
    if (this.batchTimeout) {
      clearTimeout(this.batchTimeout);
    }
    
    return new Promise((resolve, reject) => {
      this.batchTimeout = setTimeout(async () => {
        try {
          const result = await this.sendBatch(this.batchQueue);
          this.batchQueue = [];
          resolve(result);
        } catch (error) {
          reject(error);
        }
      }, 100); // Batch requests within 100ms
    });
  }
}
```

## Performance Profiling

### 1. CPU Profiling
```typescript
import * as profiler from 'v8-profiler-next';

class CPUProfiler {
  startProfiling(): void {
    profiler.startProfiling('accessibility-scan', true);
  }

  stopProfiling(): profiler.Profile {
    return profiler.stopProfiling('accessibility-scan');
  }

  analyzeProfile(profile: profiler.Profile): void {
    const topFunctions = profile.getTopDownProfile();
    console.log('Top CPU consumers:', topFunctions);
  }
}
```

### 2. Memory Profiling
```typescript
class MemoryProfiler {
  takeHeapSnapshot(): void {
    const snapshot = profiler.takeSnapshot();
    snapshot.export()
      .pipe(fs.createWriteStream(`heap-${Date.now()}.heapsnapshot`))
      .on('finish', () => {
        snapshot.delete();
      });
  }
}
```

## Performance Testing Automation

### 1. CI/CD Integration
```yaml
# GitHub Actions performance workflow
name: Performance Tests
on: [push, pull_request]
jobs:
  performance:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
      - run: npm ci
      - run: npm run test:performance
      - run: npm run benchmark
      - name: Upload performance report
        uses: actions/upload-artifact@v3
        with:
          name: performance-report
          path: performance-report.json
```

### 2. Performance Regression Detection
```typescript
class PerformanceRegressionDetector {
  async detectRegression(currentMetrics: any, baselineMetrics: any): Promise<boolean> {
    const thresholds = {
      scanTime: 1.2, // 20% increase
      memoryUsage: 1.1, // 10% increase
      cpuUsage: 1.15 // 15% increase
    };

    for (const [metric, threshold] of Object.entries(thresholds)) {
      const current = currentMetrics[metric];
      const baseline = baselineMetrics[metric];
      
      if (current / baseline > threshold) {
        console.warn(`Performance regression detected in ${metric}`);
        return true;
      }
    }

    return false;
  }
}
```

## Memory Alert Management

### Alert Settings
- **Threshold**: 90% memory usage
- **Check Interval**: 5 minutes
- **Cooldown Period**: 15 minutes
- **Max Alerts per Session**: 3
- **Alert Type**: Non-modal notifications

### Managing Alerts
Use the command `pluro.manageMemoryAlerts` to:
- Reset alert count
- View alert statistics
- Temporarily disable alerts
- Re-enable alerts

### Alert Actions
When a memory alert appears, you can:
- **Clear Cache**: Immediately clear memory cache
- **Show Details**: View detailed memory usage
- **Dismiss**: Ignore the alert

## Performance Monitoring

### Memory Usage Monitoring
The system continuously monitors memory usage and provides:
- Real-time memory statistics
- Automatic cache cleanup
- Intelligent alert management
- Performance optimization suggestions

### Cache Performance
- **Hit Rate**: Target > 85%
- **Cache Size**: Up to 200 files
- **TTL**: 15 minutes per entry
- **Cleanup**: Every 30 minutes

### Scanner Performance
- **Concurrent Scans**: 4-6 depending on workspace size
- **File Size Limit**: 2MB (increased from 1MB)
- **Batch Processing**: Optimized for large workspaces
- **Error Recovery**: Automatic retry mechanisms

## Troubleshooting Performance Issues

### High Memory Usage
1. Use `pluro.showMemoryUsage` to check current usage
2. Use `pluro.clearMemoryCache` to free memory
3. Use `pluro.manageMemoryAlerts` to adjust alert settings
4. Consider restarting VS Code if usage is consistently high

### Slow Scanning
1. Check file size limits in settings
2. Reduce concurrent scan count for large workspaces
3. Exclude unnecessary folders from scanning
4. Clear cache if it's too large

### Frequent Alerts
1. Use `pluro.manageMemoryAlerts` to reset alert count
2. Temporarily disable alerts if needed
3. Check for memory leaks in your code
4. Consider increasing memory limits in VS Code settings

## Best Practices

### For Large Projects
- Use workspace-specific settings
- Exclude build and dependency folders
- Enable parallel scanning only for smaller files
- Monitor memory usage regularly

### For Small Projects
- Enable aggressive caching
- Use higher file size limits
- Enable all scanners for thorough checking
- Regular cache cleanup not needed

### General Optimization
- Keep VS Code updated
- Monitor extension performance
- Use appropriate file exclusions
- Regular workspace cleanup 