Overview
TUIOS implements several performance optimizations to maintain 60 FPS rendering even with multiple windows and dynamic terminal content. Key techniques include style caching, viewport culling, memory pooling, and adaptive refresh rates.Style Caching
How It Works
Location:internal/app/stylecache.go
The style cache dramatically reduces allocations by reusing Lipgloss style objects:
stylecache.go:120-153):
- Hash cell attributes: Combine FG, BG, bold, italic, cursor state
- Cache lookup: Check if style exists (read lock)
- Return cached: Return existing style on hit
- Create and cache: Build new style on miss, store in cache
- Evict on full: Remove half the entries when cache reaches max size
Performance Impact
Expected improvements:| Scenario | Before | After | Improvement |
|---|---|---|---|
| Vim editing | 15% CPU | 11% CPU | ~27% reduction |
| htop running | 22% CPU | 19% CPU | ~14% reduction |
| 4x windows idle | 8% CPU | 5% CPU | ~38% reduction |
- 1024 entries ≈ 200 KB
- 2048 entries ≈ 400 KB
- 4096 entries ≈ 800 KB
Cache Statistics
View statistics: PressCtrl+B, D, c (debug prefix + cache stats)
- 95%+ hit rate: Optimal performance
- 85-95% hit rate: Good, cache working well
- 70-85% hit rate: Fair, consider increasing cache size
- Below 70% hit rate: Workload doesn’t benefit from caching
Tuning Cache Size
Recommended sizes:| Terminal Usage | Cache Size | Rationale |
|---|---|---|
| Basic shells | 512 | Low style diversity |
| Text editors | 1024 (default) | Moderate diversity |
| Syntax highlighting | 2048 | High color variety |
| Multiple busy windows | 4096 | Many concurrent styles |
internal/app/stylecache.go:231:
Viewport Culling
Window Visibility Check
Location:internal/app/render.go:57-64
Windows outside the visible viewport are skipped entirely:
- No VT buffer parsing for off-screen windows
- No style application
- No layer composition
- Significant CPU savings with many windows
Partial Visibility Optimization
Location:internal/app/render.go:67-69
Partially visible windows use lightweight rendering:
Adaptive Refresh Rates
Tick Rate Adjustment
Location:internal/app/update.go
TUIOS adjusts rendering frequency based on activity level:
| State | Tick Rate | Use Case |
|---|---|---|
| Focused window active | 60 Hz | Interactive use (vim, shell) |
| Background windows | 20 Hz | Monitoring (htop, logs) |
| Drag/resize interaction | 30 Hz | Smooth mouse operations |
| Idle (no changes) | Frame skip | No terminals updating |
Background Window Throttling
Location:internal/app/os.go:1170-1181
Background windows update every 3rd tick (~20Hz instead of 60Hz):
Memory Pooling
Object Pools
Location:internal/pool/pool.go
Object pools reuse allocations to reduce GC pressure:
Pooled Types
| Pool | Use Case | Size |
|---|---|---|
StringBuilder | Terminal content assembly | Variable |
ByteSlice | PTY I/O buffers | 32 KB |
LayerSlice | Layer composition | 16 layers |
HighlightGrid | Selection highlighting | Variable |
- Reduced allocations per frame
- Lower GC pause times
- Better memory locality
Frame Skipping
Idle Detection
Location:internal/app/os.go:108-109
TUIOS skips rendering when no content changes are detected:
internal/app/render.go:151-153):
- Terminal content change (new PTY output)
- Active animations
- User input (keyboard/mouse)
- Mode change
- Workspace switch
Content Caching
Window Layer Cache
Location:internal/app/render.go:83-86
Each window caches its rendered layer:
- ContentDirty: PTY output changed (new text)
- PositionDirty: Window moved or resized
- Dirty: Full invalidation (theme change, etc.)
internal/terminal/window.go for cache management.
Scrollback Optimization
Location:internal/vt/scrollback.go
Scrollback buffer uses circular buffer for efficient history:
- O(1) append (no reallocation)
- Fixed memory usage
- Fast scrollback navigation
Z-Index Optimization
Layer Stacking
Location:internal/app/render.go:115-118
Windows are stacked by priority:
| Window State | Z-Index |
|---|---|
| Background windows | 0-(N-2) |
| Focused window | N-1 |
| Animating windows | 1000 |
| Overlays (dock, help) | 2000+ |
Concurrency Optimizations
PTY Polling
Per-window goroutines read from PTY without blocking the UI:- Non-blocking I/O
- Parallel terminal updates
- Cancellable with context
Mutex Protection
Location:internal/app/os.go:105
Shared state uses read-write locks:
Performance Monitoring
Debug Overlays
PressCtrl+B, D to open debug menu:
c: Style cache statisticsl: Log viewers: System resource usage
Profiling
Build with profiling enabled:pprof:
Best Practices
For Users
- Limit dynamic windows: Avoid running
btopin 10+ windows simultaneously - Use minimization: Minimize unused windows to skip rendering
- Increase cache size: If using heavy syntax highlighting (2048-4096)
- Monitor statistics: Check cache hit rate periodically
For Developers
- Profile before optimizing: Use
pprofto find bottlenecks - Benchmark changes: Use Go benchmarks to measure impact
- Check cache stats: Ensure optimizations improve hit rate
- Avoid premature optimization: Focus on algorithmic improvements first
Related Documentation
- Architecture - Overall design
- Components - Component details
- Configuration - Performance settings