The Question
FE DesignReal-time Collaborative Whiteboard Architecture
Design a frontend architecture for a high-performance, real-time collaborative whiteboard. The system must handle low-latency vector graphics synchronization, conflict resolution for concurrent multi-user editing, and efficient network utilization for mobile-friendly bandwidth consumption.
HTML5 Canvas
WebSocket
CRDT
Binary Serialization
IndexedDB
requestAnimationFrame
Questions & Insights
Clarifying Questions
What is the maximum number of concurrent collaborators per board?
Assumption: Designed for small to medium groups (up to 20 users) to ensure low-latency synchronization and manageable conflict resolution.
What level of "Undo/Redo" is expected?
Assumption: Local undo/redo (reverting the current user's actions) is the priority for MVP, as global undo/redo requires complex shared history management.
Should the board persist across sessions?
Assumption: Yes, the state is persisted in a database, but for the MVP, we will focus on the real-time synchronization layer.
What types of objects are supported?
Assumption: Freehand paths, basic geometric shapes (rectangles, circles), and simple text blocks.
Crash Strategy
Core Bottleneck: Real-time synchronization of high-frequency drawing data without saturating the network or causing jitter.
Step 1: Data Representation: Use a vector-based object model (JSON/Binary) rather than raster data. Each shape is an entity with a unique ID.
Step 2: State Synchronization: Implement a CRDT-based (Conflict-free Replicated Data Type) approach using a library like Yjs to handle concurrent edits and eventual consistency automatically.
Step 3: Network Optimization: Use WebSockets for low-latency full-duplex communication and throttle high-frequency events (like mouse moves) to reduce bandwidth.
Step 4: Rendering Strategy: Use a double-buffered HTML5 Canvas for performance, separating the static "background" (completed shapes) from the "active" layer (currently drawing).
Elite Bonus Points
Binary Serialization: Use Protocol Buffers (Protobuf) or MessagePack instead of JSON for the WebSocket payload to minimize bandwidth usage.
Fractional Indexing: Use "Lexical Sorting" for object Z-index to allow users to insert objects between layers without re-indexing the entire board.
Optimistic UI with Local Echo: Render the user's input immediately on a local "draft" layer before the server confirms the broadcast.
Offscreen Canvas: Utilize
OffscreenCanvas in a Web Worker to keep the main thread responsive during heavy rendering operations.Design Breakdown
Requirements
Functional Requirements:
Real-time multi-user drawing and text editing.
Toolbar for tool selection (Pen, Shapes, Text).
Local Undo/Redo of the user's own actions.
Presence indicators (remote cursors).
Non-Functional Requirements:
Latency: Sub-100ms UI response for local drawing; sub-200ms for remote sync.
Scalability: Support hundreds of objects on a single board without frame drops.
Bandwidth: Minimal data transfer (send only deltas/vectors).
Reliability: Automatic reconnection and state resync after network drops.
Design Summary
Concise Summary: A vector-based collaborative canvas utilizing a CRDT engine for state management and WebSockets for delta-based synchronization.
Major Components:
Whiteboard Engine: Manages the HTML5 Canvas lifecycle, coordinate transformations, and tool-based event handling.
CRDT State Manager: Maintains a shared immutable-like state of all board objects, handling conflict resolution and history.
Sync Provider: Manages WebSocket connections and broadcasts lightweight state deltas.
Presence Manager: Tracks and renders ephemeral data like remote cursor positions.
CUJ Walkthrough:
Drawing: User selects Pen -> Engine captures
mousemove -> Engine updates local CRDT map -> Sync Provider broadcasts delta -> Remote clients receive delta and re-render.Text Editing: User clicks text box -> Engine spawns a hidden input/textarea -> On input, updates CRDT text property -> Sync Provider broadcasts character deltas.
Simplicity Audit: This design avoids complex "Locking" mechanisms by using CRDTs. It avoids high bandwidth costs by sending vectors instead of pixels.
Architecture Decision Rationale:
CRDTs (e.g., Yjs) are chosen because they solve the hardest part of collaboration (conflicts) out-of-the-box, allowing the MVP to focus on UI.
Canvas is chosen over SVG for better performance when handling thousands of path points (typical in freehand drawing).
System Diagram
Architecture Deep Dive
Presentation Layer
Component Hierarchy: The
App Shell provides the global context (Auth). Whiteboard Layout manages the workspace. The Canvas Page contains the Whiteboard Engine (the core <canvas>) and overlays like Toolbar and User Cursors.Interaction Layer: Event listeners capture
mousedown, mousemove, and mouseup. Coordinates are normalized to a global "World Space" to account for zoom/pan.Rendering Layer: We use a RequestAnimationFrame (rAF) loop. To optimize, we only redraw "dirty" regions or use two canvas layers: a "Static Layer" for existing objects and a "Top Layer" for the current active stroke to prevent full-board redraws at 60fps.
UI Frameworks: React/Vue for the UI chrome (Toolbar, Menus), but the Canvas itself is managed via a vanilla JS Engine to bypass framework overhead.
Application Layer
Data Fetching Layer: Initial board state is fetched via REST/GraphQL. Subsequent updates are purely delta-based via WebSockets.
State Management Layer: Yjs is the backbone. It stores board objects in a
Y.Map. When a user draws, a new Y.Polyline is added. CRDT ensures that if two users edit the same text, the results merge predictably.Undo & Redo: Implemented via Yjs
UndoManager. It tracks local changes and allows "stepping back" through the local mutation stack without affecting other users' concurrent edits.Domain Layer
Business Rules: Validation of shape bounds, enforcement of maximum stroke lengths, and calculation of bounding boxes for selection.
Entities / Models:
Shape (id, type, color, points, transform). Text (id, value, fontSize). All models are decoupled from the rendering engine; the engine simply reads these properties to draw.Inter-layer Contracts: The
Whiteboard Engine communicates with the CRDT State Manager through an Observer pattern—whenever the CRDT state changes (locally or remotely), the Engine triggers a re-render.Infrastructure Layer
API / Network: WebSockets (via Socket.io or AWS AppSync) provide the real-time channel. For "minimal bandwidth," we throttle
mousemove events to 30ms and use binary encoding.Storage: The CRDT state is persisted in
IndexedDB locally for offline support and "Instant Load" on return, then synchronized with the server's authoritative database.Wrap Up
Wrap-up
Trade-offs: We chose Canvas over SVG. While SVG is easier to style with CSS, Canvas performs significantly better for complex freehand drawings with thousands of points.
Optimization: To handle "minimal bandwidth," we use Path Simplification (e.g., Ramer-Douglas-Peucker algorithm) to reduce the number of points in a freehand line before broadcasting it.
Future Scale: For massive boards, we would implement Spatial Indexing (Quadtrees) to only render objects within the user's current viewport.