# Chapter 04: User Interface Architecture - Web Components and Real-Time Communication
The General Bots User Interface (gbui) system implements a sophisticated, component-based architecture for creating responsive, real-time conversational experiences across multiple platforms and devices. This chapter provides comprehensive technical documentation on the UI framework, rendering pipeline, WebSocket communication protocols, and interface customization capabilities.
## Executive Summary
The gbui system represents a modern approach to conversational UI development, implementing a lightweight, standards-based architecture that eliminates framework dependencies while providing enterprise-grade capabilities. The system leverages native Web Components, WebSocket protocols, and progressive enhancement strategies to deliver sub-second response times and seamless user experiences across desktop, mobile, and embedded platforms.
## System Architecture Overview
### UI Component Stack
The user interface implements a layered architecture for maximum flexibility and performance:
```
┌─────────────────────────────────────────────────────────────────┐
│ Presentation Layer │
│ (HTML5, CSS3, Web Components) │
├─────────────────────────────────────────────────────────────────┤
│ Interaction Layer │
│ (Event Handling, Gesture Recognition, A11y) │
├─────────────────────────────────────────────────────────────────┤
│ Communication Layer │
│ (WebSocket, Server-Sent Events, REST API) │
├─────────────────────────────────────────────────────────────────┤
│ State Management │
│ (Session Storage, IndexedDB, Service Workers) │
├─────────────────────────────────────────────────────────────────┤
│ Rendering Pipeline │
│ (Virtual DOM, Incremental Updates, GPU Acceleration) │
└─────────────────────────────────────────────────────────────────┘
```
### Technical Specifications
| Component | Technology | Performance Target | Browser Support |
|-----------|------------|-------------------|-----------------|
| Rendering Engine | Native DOM + Virtual DOM diffing | 60 FPS animations | Chrome 90+, Firefox 88+, Safari 14+ |
| Communication | WebSocket (RFC 6455) | <100ms latency | All modern browsers |
| State Management | IndexedDB + LocalStorage | <5ms read/write | All modern browsers |
| Component System | Web Components v1 | <50ms initialization | Chrome, Firefox, Safari, Edge |
| Styling Engine | CSS Grid + Flexbox + Custom Properties | <16ms paint | All modern browsers |
| Build Size | Vanilla JS (no framework) | <50KB gzipped | IE11+ with polyfills |
## Template Architecture
### Template Processing Pipeline
The gbui template system implements a multi-stage processing pipeline:
```javascript
class TemplateProcessor {
/**
* Advanced template processing with optimization
*/
constructor() {
this.templateCache = new Map();
this.componentRegistry = new Map();
this.renderQueue = [];
this.rafId = null;
}
processTemplate(templatePath, data) {
// Stage 1: Template loading and caching
const template = this.loadTemplate(templatePath);
// Stage 2: Template parsing and AST generation
const ast = this.parseTemplate(template);
// Stage 3: Data binding and interpolation
const boundAST = this.bindData(ast, data);
// Stage 4: Component resolution
const resolvedAST = this.resolveComponents(boundAST);
// Stage 5: Optimization pass
const optimizedAST = this.optimizeAST(resolvedAST);
// Stage 6: DOM generation
const domFragment = this.generateDOM(optimizedAST);
// Stage 7: Hydration and event binding
this.hydrate(domFragment);
return domFragment;
}
parseTemplate(template) {
/**
* Convert HTML template to Abstract Syntax Tree
*/
const parser = new DOMParser();
const doc = parser.parseFromString(template, 'text/html');
return this.buildAST(doc.body);
}
buildAST(node) {
const ast = {
type: node.nodeType === 1 ? 'element' : 'text',
tag: node.tagName?.toLowerCase(),
attributes: {},
children: [],
directives: {},
events: {}
};
if (node.nodeType === 1) {
// Process attributes
for (const attr of node.attributes) {
if (attr.name.startsWith('data-')) {
ast.directives[attr.name.slice(5)] = attr.value;
} else if (attr.name.startsWith('on')) {
ast.events[attr.name.slice(2)] = attr.value;
} else {
ast.attributes[attr.name] = attr.value;
}
}
// Process children
for (const child of node.childNodes) {
if (child.nodeType === 1 || child.nodeType === 3) {
ast.children.push(this.buildAST(child));
}
}
} else if (node.nodeType === 3) {
ast.content = node.textContent;
}
return ast;
}
}
```
### Template Types and Specifications
#### default.gbui - Full Desktop Interface
Complete workspace implementation with modular applications:
```html
```
#### single.gbui - Minimalist Chat Interface
Lightweight, focused chat implementation:
```html
Chat
```
## WebSocket Communication Protocol
### Protocol Specification
Real-time bidirectional communication implementation:
```typescript
interface WebSocketProtocol {
// Message Types
enum MessageType {
HANDSHAKE = 'handshake',
MESSAGE = 'message',
TYPING = 'typing',
PRESENCE = 'presence',
ERROR = 'error',
HEARTBEAT = 'heartbeat',
ACKNOWLEDGE = 'acknowledge'
}
// Base Message Structure
interface BaseMessage {
id: string;
type: MessageType;
timestamp: number;
version: string;
}
// Message Implementations
interface ChatMessage extends BaseMessage {
type: MessageType.MESSAGE;
content: string;
sender: 'user' | 'bot';
metadata?: {
tokens?: number;
processingTime?: number;
confidence?: number;
sources?: string[];
};
}
interface TypingMessage extends BaseMessage {
type: MessageType.TYPING;
isTyping: boolean;
sender: string;
}
interface PresenceMessage extends BaseMessage {
type: MessageType.PRESENCE;
status: 'online' | 'away' | 'offline';
lastSeen?: number;
}
}
```
### Connection Management
Robust connection handling with automatic recovery:
```javascript
class WebSocketManager {
constructor(url) {
this.url = url;
this.ws = null;
this.reconnectAttempts = 0;
this.maxReconnectAttempts = 5;
this.reconnectDelay = 1000;
this.heartbeatInterval = 30000;
this.messageQueue = [];
this.isConnected = false;
this.connect();
}
connect() {
this.ws = new WebSocket(this.url);
this.ws.onopen = () => {
this.isConnected = true;
this.reconnectAttempts = 0;
// Start heartbeat
this.startHeartbeat();
// Flush message queue
this.flushQueue();
// Send handshake
this.send({
type: 'handshake',
version: '1.0.0',
capabilities: ['typing', 'presence', 'files']
});
};
this.ws.onmessage = (event) => {
const message = JSON.parse(event.data);
this.handleMessage(message);
};
this.ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
this.ws.onclose = () => {
this.isConnected = false;
this.stopHeartbeat();
this.attemptReconnect();
};
}
attemptReconnect() {
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
console.error('Max reconnection attempts reached');
this.onMaxReconnectFailed();
return;
}
this.reconnectAttempts++;
const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
console.log(`Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})`);
setTimeout(() => {
this.connect();
}, delay);
}
startHeartbeat() {
this.heartbeatTimer = setInterval(() => {
if (this.isConnected) {
this.send({ type: 'heartbeat' });
}
}, this.heartbeatInterval);
}
send(data) {
const message = {
...data,
id: this.generateId(),
timestamp: Date.now()
};
if (this.isConnected && this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify(message));
} else {
// Queue message for later delivery
this.messageQueue.push(message);
}
return message.id;
}
flushQueue() {
while (this.messageQueue.length > 0) {
const message = this.messageQueue.shift();
this.ws.send(JSON.stringify(message));
}
}
}
```
## Performance Optimization
### Rendering Performance
Techniques for maintaining 60 FPS:
```javascript
class RenderOptimizer {
constructor() {
this.renderQueue = [];
this.isRendering = false;
this.rafId = null;
// Virtual DOM for diff calculations
this.virtualDOM = {
messages: [],
state: {}
};
// DOM references cache
this.domCache = new WeakMap();
}
scheduleRender(updates) {
// Batch updates
this.renderQueue.push(...updates);
if (!this.isRendering) {
this.isRendering = true;
this.rafId = requestAnimationFrame(() => this.performRender());
}
}
performRender() {
const startTime = performance.now();
// Process render queue
const updates = this.renderQueue.splice(0, 100); // Limit batch size
// Calculate minimal DOM updates
const patches = this.calculatePatches(updates);
// Apply patches
this.applyPatches(patches);
// Continue rendering if queue not empty
if (this.renderQueue.length > 0) {
this.rafId = requestAnimationFrame(() => this.performRender());
} else {
this.isRendering = false;
}
// Monitor performance
const renderTime = performance.now() - startTime;
if (renderTime > 16.67) {
console.warn(`Render took ${renderTime}ms - possible jank`);
}
}
calculatePatches(updates) {
const patches = [];
for (const update of updates) {
const oldVNode = this.virtualDOM[update.path];
const newVNode = update.value;
const diff = this.diff(oldVNode, newVNode);
if (diff) {
patches.push({
path: update.path,
diff: diff
});
}
// Update virtual DOM
this.virtualDOM[update.path] = newVNode;
}
return patches;
}
}
```
### Resource Loading
Progressive loading strategies:
```javascript
class ResourceLoader {
constructor() {
this.loadQueue = [];
this.loadingResources = new Set();
this.resourceCache = new Map();
// Intersection Observer for lazy loading
this.observer = new IntersectionObserver(
(entries) => this.handleIntersection(entries),
{
rootMargin: '50px',
threshold: 0.01
}
);
}
async loadCriticalResources() {
// Critical CSS
await this.loadCSS('/css/critical.css', { priority: 'high' });
// Critical JavaScript
await this.loadScript('/js/core.js', { priority: 'high' });
// Preload fonts
this.preloadFonts([
'/fonts/inter-var.woff2',
'/fonts/jetbrains-mono.woff2'
]);
// Prefetch likely navigation targets
this.prefetchResources([
'/api/user',
'/api/conversations/recent'
]);
}
async loadCSS(href, options = {}) {
return new Promise((resolve, reject) => {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = href;
if (options.priority === 'high') {
link.fetchpriority = 'high';
}
link.onload = resolve;
link.onerror = reject;
document.head.appendChild(link);
});
}
preloadFonts(fonts) {
fonts.forEach(font => {
const link = document.createElement('link');
link.rel = 'preload';
link.as = 'font';
link.type = 'font/woff2';
link.href = font;
link.crossOrigin = 'anonymous';
document.head.appendChild(link);
});
}
}
```
## Accessibility Implementation
### WCAG 2.1 AAA Compliance
Comprehensive accessibility features:
```javascript
class AccessibilityManager {
constructor() {
this.announcer = this.createAnnouncer();
this.focusTrap = null;
this.prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
this.initializeA11y();
}
initializeA11y() {
// Skip navigation links
this.addSkipLinks();
// Keyboard navigation
this.setupKeyboardNav();
// Screen reader announcements
this.setupAnnouncements();
// Focus management
this.setupFocusManagement();
// High contrast mode detection
this.detectHighContrast();
}
createAnnouncer() {
const announcer = document.createElement('div');
announcer.setAttribute('role', 'status');
announcer.setAttribute('aria-live', 'polite');
announcer.setAttribute('aria-atomic', 'true');
announcer.className = 'sr-only';
document.body.appendChild(announcer);
return announcer;
}
announce(message, priority = 'polite') {
this.announcer.setAttribute('aria-live', priority);
this.announcer.textContent = message;
// Clear after announcement
setTimeout(() => {
this.announcer.textContent = '';
}, 1000);
}
setupKeyboardNav() {
document.addEventListener('keydown', (e) => {
// Keyboard shortcuts
if (e.altKey) {
switch(e.key) {
case '1': this.navigateTo('chat'); break;
case '2': this.navigateTo('drive'); break;
case '3': this.navigateTo('tasks'); break;
case '4': this.navigateTo('mail'); break;
case '/': this.focusSearch(); break;
}
}
// Tab trap for modals
if (this.focusTrap && e.key === 'Tab') {
this.handleTabTrap(e);
}
// Escape key handling
if (e.key === 'Escape') {
this.handleEscape();
}
});
}
}
```
## Security Considerations
### Content Security Policy
Comprehensive CSP implementation:
```html
```
### XSS Prevention
Input sanitization and output encoding:
```javascript
class SecurityManager {
sanitizeHTML(html) {
const policy = {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'br', 'p', 'code', 'pre'],
ALLOWED_ATTR: ['href', 'title', 'target'],
ALLOW_DATA_ATTR: false,
RETURN_DOM: false,
RETURN_DOM_FRAGMENT: false,
RETURN_TRUSTED_TYPE: true
};
return DOMPurify.sanitize(html, policy);
}
escapeHTML(text) {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'/': '/'
};
return text.replace(/[&<>"'/]/g, char => map[char]);
}
}
```
## Summary
The gbui system provides a complete, production-ready user interface framework that delivers enterprise-grade performance while maintaining simplicity and accessibility. Through careful optimization, progressive enhancement, and standards compliance, the system achieves sub-second response times and smooth 60 FPS rendering across all supported platforms.