Skip to content

Architecture

Elyas Rahimi edited this page Jan 21, 2026 · 1 revision

Grob Browser Architecture

Overview

Grob is a modular web browser engine written in Rust. The architecture emphasizes separation of concerns, where each component handles a specific aspect of web rendering and display.

High-Level Architecture

┌─────────────────────────────────────┐
│      Browser Application            │
│    (UI, Window, Events)             │
├─────────────────────────────────────┤
│                                     │
│      Grob Engine (Core)             │
│                                     │
│  ┌────────────────────────────────┐ │
│  │  Parser (HTML, CSS)            │ │
│  │  ↓                             │ │
│  │  DOM (Document Tree)           │ │
│  │  ↓                             │ │
│  │  Style (CSS Processing)        │ │
│  │  ↓                             │ │
│  │  Layout (Positioning)          │ │
│  │  ↓                             │ │
│  │  Paint (Rendering)             │ │
│  └────────────────────────────────┘ │
│                                     │
│  Supporting Modules:                │
│  • Font (Typography)                │
│  • Network (HTTP Requests)          │
│  • JavaScript (Scripting)           │
│  • Platform (OS Abstraction)        │
└─────────────────────────────────────┘

Rendering Pipeline

The core functionality follows a linear pipeline:

1. Network Phase

Module: Network

  • User navigates to URL
  • Network Manager fetches HTML and resources
  • Resources are cached for performance

2. Parsing Phase

Module: Parser

  • HTML is parsed into a DOM tree
  • CSS is parsed into stylesheets
  • Errors are handled gracefully

3. DOM Phase

Module: DOM

  • Document tree is built in memory
  • Elements are organized hierarchically
  • Attributes and content are stored

4. Style Phase

Module: Style

  • CSS rules are matched to DOM elements
  • Cascade and inheritance rules applied
  • Computed styles calculated

5. Layout Phase

Module: Layout

  • CSS box model calculated
  • Element positions determined
  • Dimensions computed for all elements

6. Paint Phase

Module: Paint

  • Drawing instructions generated
  • Elements rendered in proper order
  • Text glyphs rendered

7. Display Phase

Module: Browser

  • Pixel buffer updated
  • Window is refreshed
  • Result displayed to user

Component Relationships

Data Flow

HTML Input → Network → Parser → DOM → Style → Layout → Paint → Browser Display
     ↑                                                              ↓
     └──────────── JavaScript (Dynamic Updates) ────────────────────┘

Supporting Services

Font Module          ← needed by Layout & Paint for text metrics and glyphs
Network Module       ← needed by Parser & Browser for resource fetching
JavaScript Module    ← interacts with DOM, Style, and Layout
Platform Module      ← used by all modules for OS operations

Key Architectural Principles

1. Modularity

Each component has a single, well-defined responsibility:

  • Parser handles parsing only
  • Layout calculates dimensions only
  • Paint renders output only

2. Separation of Concerns

Clear boundaries between components:

  • No circular dependencies
  • Well-defined interfaces
  • Independent testing possible

3. Immutability and Borrowing

Rust's ownership system ensures:

  • Memory safety without GC
  • Prevention of data races
  • Clear resource ownership

4. Composition Over Inheritance

Building blocks are composed:

  • Modules don't inherit from each other
  • Data structures are composed
  • Functionality is combined

5. Cross-Platform Support

Platform Module abstraction:

  • Same code runs on Windows, macOS, Linux
  • Platform-specific implementations hidden
  • OS details encapsulated

Process Flow

Page Load Process

1. User enters URL
   ↓
2. Browser sends HTTP request (Network)
   ↓
3. HTML response received
   ↓
4. HTML parsed to DOM (Parser)
   ↓
5. CSS parsed to stylesheets (Parser)
   ↓
6. CSS rules applied to DOM (Style)
   ↓
7. Layout tree calculated (Layout)
   ↓
8. Content rendered (Paint)
   ↓
9. Displayed in window (Browser)
   ↓
10. JavaScript executed (JavaScript)
   ↓
11. DOM updated if needed
   ↓
12. Layout/Paint recalculated
   ↓
13. Updated content displayed

Event Handling

User Input (click, keyboard, etc.)
   ↓
Browser captures event
   ↓
JavaScript event listeners triggered
   ↓
DOM updated by scripts
   ↓
Style recalculated
   ↓
Layout recalculated
   ↓
Paint regenerated
   ↓
Display updated

Module Dependencies

Browser
  └── depends on: Engine

Engine
  ├── Parser
  │   └── depends on: (nothing in engine)
  │
  ├── DOM
  │   └── depends on: (nothing in engine)
  │
  ├── Style
  │   └── depends on: DOM, Parser
  │
  ├── Layout
  │   ├── depends on: Style, Font, DOM
  │
  ├── Paint
  │   ├── depends on: Layout, Style, Font
  │
  ├── Font
  │   ├── depends on: Platform, Network
  │
  ├── Network
  │   └── depends on: Platform
  │
  ├── JavaScript
  │   ├── depends on: DOM, Style, Layout
  │
  └── Platform
      └── depends on: (nothing - lowest level)

Data Structures

Core Structures

Structure Module Purpose
Dom DOM Document tree representation
Stylesheet Parser CSS rules collection
Style Style Computed CSS properties
LayoutBox Layout Layout information
PaintInstruction Paint Rendering operation

Memory Management

Ownership Model

  • Owned: Values owned by single structure
  • Borrowed: References to data
  • Shared: Arc for thread-safe sharing
  • Garbage Collection: None (Rust's borrow checker)

Resource Lifecycle

Allocation: Module requests resource
   ↓
Initialization: Resource is set up
   ↓
Use: Resource is used by module
   ↓
Cleanup: Rust automatically frees when no longer needed

Performance Characteristics

Complexity Analysis

Phase Complexity Notes
Parsing O(n) Linear in input size
Style O(n*m) n elements, m rules
Layout O(n) Single pass for simple layouts
Paint O(n) Render all visible elements

Optimization Strategies

  • Incremental Updates: Update only changed parts
  • Caching: Cache expensive computations
  • Lazy Evaluation: Compute only when needed
  • Batching: Group operations efficiently

Error Handling

Error Propagation

Lower Level Error
   ↓
Wrapped in Result/Option
   ↓
Propagated up call stack
   ↓
Handled at top level (Browser)
   ↓
User sees graceful failure

Recovery Mechanisms

  • Parsing Errors: Continue with partial DOM
  • Layout Errors: Use fallback dimensions
  • Rendering Errors: Skip rendering problematic element
  • Network Errors: Retry with backoff

Extensibility

Adding New Features

  1. New CSS Property:

    • Add to Style module
    • Handle in Layout/Paint as needed
  2. New HTML Element:

    • Parser already handles generically
    • Style/Layout/Paint handle via attributes
  3. New Layout Algorithm:

    • Add to Layout module
    • Keep interface consistent
  4. New Platform:

    • Implement Platform module for new OS
    • Rest of code unchanged

Concurrency (Planned)

Future enhancements for multi-threading:

  • Network Thread: Background resource fetching
  • Rendering Thread: Separate render thread
  • JavaScript Thread: Isolated script execution
  • Layout Thread: Parallel layout calculations

Caching Strategy

Multiple Cache Levels

  1. Memory Cache: Fast, volatile
  2. Disk Cache: Persistent storage
  3. Glyph Cache: Font rendering cache
  4. Layout Cache: Layout computation results

Invalidation

Cache invalidation when:

  • DOM changes
  • Styles are modified
  • Window is resized
  • Resources are updated

Testing Architecture

Module Testing

Each module has tests:

  • Unit tests for individual functions
  • Integration tests for module interactions
  • Property-based tests for algorithms

Test Coverage

  • Parser: Test various HTML/CSS inputs
  • Layout: Test box model and positioning
  • Paint: Test rendering output
  • Integration: Test complete pipeline

Version Compatibility

API Stability

  • Public interfaces remain stable
  • Internal details can change
  • Deprecation warnings for changes
  • Migration guides provided

Standards Compliance

  • HTML5 specification
  • CSS Cascading and Inheritance Level 3
  • DOM Level 2 Events
  • ECMAScript 5+ (planned)

Future Architecture Changes

Planned enhancements:

  • Multi-threading: Parallel rendering
  • GPU Acceleration: Hardware rendering
  • WebAssembly: WASM support
  • Web APIs: Modern JavaScript APIs
  • Service Workers: Offline support
  • Progressive Enhancement: Better fallbacks

Clone this wiki locally