ObsiViewer/docs/PERFORMENCE/references/ARCHITECTURE_DIAGRAMS.md

28 KiB
Raw Blame History

Architecture Diagrams - Performance Optimization

Current Architecture (SLOW )

┌─────────────────────────────────────────────────────────────────────────┐
│ User opens application                                                  │
└──────────────────────────┬──────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Browser requests /api/vault                                             │
│ (Load ALL notes with FULL content)                                      │
└──────────────────────────┬──────────────────────────────────────────────┘
                           │
                           ▼ (5-10 seconds)
┌─────────────────────────────────────────────────────────────────────────┐
│ Server: loadVaultNotes(vaultDir)                                        │
│ ├─ Walk filesystem recursively                                          │
│ ├─ For EACH file:                                                       │
│ │  ├─ Read file content                                                 │
│ │  ├─ enrichFrontmatterOnOpen() ← EXPENSIVE (YAML parsing, I/O)        │
│ │  ├─ Extract title, tags                                               │
│ │  └─ Calculate stats                                                   │
│ └─ Return 5-10MB JSON                                                   │
└──────────────────────────┬──────────────────────────────────────────────┘
                           │
                           ▼ (5-10 seconds)
┌─────────────────────────────────────────────────────────────────────────┐
│ Network: Send large JSON payload (5-10MB)                               │
│ ├─ Compression: gzip reduces to 1-2MB                                   │
│ └─ Transfer time: 2-5 seconds on 4G                                     │
└──────────────────────────┬──────────────────────────────────────────────┘
                           │
                           ▼ (2-3 seconds)
┌─────────────────────────────────────────────────────────────────────────┐
│ Client: Parse JSON, store in VaultService.allNotes()                    │
│ ├─ Parse 5-10MB JSON                                                    │
│ ├─ Create Note objects for all files                                    │
│ └─ Store in memory (200-300MB)                                          │
└──────────────────────────┬──────────────────────────────────────────────┘
                           │
                           ▼ (2-3 seconds)
┌─────────────────────────────────────────────────────────────────────────┐
│ Render UI                                                               │
│ ├─ NotesListComponent renders all items                                 │
│ ├─ AppShellNimbusLayoutComponent initializes                            │
│ └─ UI becomes interactive                                               │
└──────────────────────────┬──────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ ⏱️ TOTAL TIME: 15-30 SECONDS ❌                                          │
│ User can finally interact with the application                          │
└─────────────────────────────────────────────────────────────────────────┘

Proposed Architecture (FAST )

┌─────────────────────────────────────────────────────────────────────────┐
│ User opens application                                                  │
└──────────────────────────┬──────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Browser requests /api/vault/metadata                                    │
│ (Load ONLY metadata, NO content, NO enrichment)                         │
└──────────────────────────┬──────────────────────────────────────────────┘
                           │
                           ▼ (0.5-1 second)
┌─────────────────────────────────────────────────────────────────────────┐
│ Server: loadVaultMetadataOnly(vaultDir)                                 │
│ ├─ Walk filesystem recursively                                          │
│ ├─ For EACH file:                                                       │
│ │  ├─ Read file content (fast)                                          │
│ │  ├─ Extract title from first heading (fast)                           │
│ │  └─ Get file stats (fast)                                             │
│ ├─ NO enrichFrontmatterOnOpen() ← SKIPPED                               │
│ ├─ NO tag extraction ← DEFERRED                                         │
│ └─ Return 0.5-1MB JSON (metadata only)                                  │
└──────────────────────────┬──────────────────────────────────────────────┘
                           │
                           ▼ (0.2-0.5 seconds)
┌─────────────────────────────────────────────────────────────────────────┐
│ Network: Send small JSON payload (0.5-1MB)                              │
│ ├─ Compression: gzip reduces to 100-200KB                               │
│ └─ Transfer time: < 1 second on 4G                                      │
└──────────────────────────┬──────────────────────────────────────────────┘
                           │
                           ▼ (0.5-1 second)
┌─────────────────────────────────────────────────────────────────────────┐
│ Client: Parse JSON, store in VaultService.allNotesMetadata()            │
│ ├─ Parse 0.5-1MB JSON (fast)                                            │
│ ├─ Create Note objects with empty content                               │
│ └─ Store in memory (50-100MB)                                           │
└──────────────────────────┬──────────────────────────────────────────────┘
                           │
                           ▼ (1-2 seconds)
┌─────────────────────────────────────────────────────────────────────────┐
│ Render UI                                                               │
│ ├─ NotesListComponent renders all items (metadata only)                 │
│ ├─ AppShellNimbusLayoutComponent initializes                            │
│ └─ UI becomes interactive                                               │
└──────────────────────────┬──────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ ⏱️ TOTAL TIME: 2-4 SECONDS ✅                                            │
│ User can interact with the application                                  │
└──────────────────────────┬──────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ User clicks on a note                                                   │
└──────────────────────────┬──────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Browser requests /api/files?path=note.md                                │
│ (Load ONLY this note's content)                                         │
└──────────────────────────┬──────────────────────────────────────────────┘
                           │
                           ▼ (0.2-0.5 seconds)
┌─────────────────────────────────────────────────────────────────────────┐
│ Server: Load and enrich single file                                     │
│ ├─ Read file content                                                    │
│ ├─ enrichFrontmatterOnOpen() ← ONLY for this file                       │
│ ├─ Extract tags                                                         │
│ └─ Return file content                                                  │
└──────────────────────────┬──────────────────────────────────────────────┘
                           │
                           ▼ (0.2-0.5 seconds)
┌─────────────────────────────────────────────────────────────────────────┐
│ Network: Send single note content (5-50KB)                              │
└──────────────────────────┬──────────────────────────────────────────────┘
                           │
                           ▼ (0.2-0.5 seconds)
┌─────────────────────────────────────────────────────────────────────────┐
│ Client: Update note with full content                                   │
│ ├─ Parse content                                                        │
│ ├─ Update VaultService                                                  │
│ └─ Render note viewer                                                   │
└──────────────────────────┬──────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ ⏱️ TOTAL TIME: 0.5-1.5 SECONDS ✅                                        │
│ Note content displayed to user                                          │
└─────────────────────────────────────────────────────────────────────────┘

Data Flow Comparison

Current Flow (Slow)

App Start
   │
   ├─→ /api/vault (ALL files, ALL content)
   │   └─→ Server: loadVaultNotes()
   │       ├─ Walk FS: O(n)
   │       ├─ Enrich each: O(n) × expensive
   │       └─ Return: 5-10MB
   │
   ├─→ Network: 2-5s
   │
   ├─→ Client Parse: 2-3s
   │
   └─→ Render UI: 2-3s
   
Total: 15-30 seconds ❌

Proposed Flow (Fast)

App Start
   │
   ├─→ /api/vault/metadata (metadata only)
   │   └─→ Server: loadVaultMetadataOnly()
   │       ├─ Walk FS: O(n)
   │       ├─ NO enrichment: fast
   │       └─ Return: 0.5-1MB
   │
   ├─→ Network: < 1s
   │
   ├─→ Client Parse: 0.5-1s
   │
   ├─→ Render UI: 1-2s
   │
   └─→ UI Interactive: 2-4s ✅
   
User clicks note
   │
   ├─→ /api/files?path=note.md (single file)
   │   └─→ Server: Load and enrich single file
   │       ├─ Read: fast
   │       ├─ Enrich: only this file
   │       └─ Return: 5-50KB
   │
   ├─→ Network: < 1s
   │
   └─→ Client: Render: 0.5-1s
   
Total: 0.5-1.5 seconds ✅

Memory Usage Comparison

Current Architecture

┌─────────────────────────────────────────────────────┐
│ Memory Usage (1000 files)                           │
├─────────────────────────────────────────────────────┤
│ Server:                                             │
│  ├─ File handles: ~50MB                             │
│  ├─ Parsed JSON: ~100MB                             │
│  └─ Enrichment cache: ~50MB                         │
│  └─ Total: 200MB                                    │
│                                                     │
│ Client:                                             │
│  ├─ JSON payload: ~100MB                            │
│  ├─ Note objects: ~100MB                            │
│  └─ DOM nodes: ~50MB                                │
│  └─ Total: 250MB                                    │
│                                                     │
│ TOTAL: 450MB ❌                                      │
└─────────────────────────────────────────────────────┘

Proposed Architecture

┌─────────────────────────────────────────────────────┐
│ Memory Usage (1000 files)                           │
├─────────────────────────────────────────────────────┤
│ Server:                                             │
│  ├─ File handles: ~20MB                             │
│  ├─ Parsed JSON: ~10MB                              │
│  └─ Cache (optional): ~30MB                         │
│  └─ Total: 60MB                                     │
│                                                     │
│ Client:                                             │
│  ├─ JSON payload: ~5MB                              │
│  ├─ Note objects (metadata): ~20MB                  │
│  └─ DOM nodes: ~10MB                                │
│  └─ Total: 35MB                                     │
│                                                     │
│ TOTAL: 95MB ✅ (79% reduction)                      │
└─────────────────────────────────────────────────────┘

Network Payload Comparison

Current Architecture

Request: /api/vault
Response Size: 5-10 MB

Breakdown (1000 files):
├─ Metadata per file: 200 bytes
│  └─ id, title, path, dates: 200 × 1000 = 200KB
│
├─ Content per file: 5KB average
│  └─ Full markdown: 5000 × 1000 = 5MB
│
└─ Tags per file: 100 bytes
   └─ Extracted tags: 100 × 1000 = 100KB

Total: ~5.3 MB ❌
Compressed (gzip): ~1-2 MB
Transfer time (4G): 2-5 seconds

Proposed Architecture

Request 1: /api/vault/metadata
Response Size: 0.5-1 MB

Breakdown (1000 files):
├─ Metadata per file: 200 bytes
│  └─ id, title, path, dates: 200 × 1000 = 200KB
│
├─ NO content
│  └─ Saved: 5MB
│
└─ NO tags
   └─ Saved: 100KB

Total: ~0.2 MB ✅
Compressed (gzip): ~50-100 KB
Transfer time (4G): < 1 second

Request 2 (on-demand): /api/files?path=note.md
Response Size: 5-50 KB per file
Transfer time: < 1 second per file

Performance Timeline

Current (Slow) Timeline

0s    ├─ App starts
      │
1s    ├─ Network request sent
      │
3s    ├─ Server processing (loadVaultNotes)
      │
8s    ├─ Server response received
      │
10s   ├─ Network transfer complete
      │
13s   ├─ Client parsing complete
      │
15s   ├─ UI rendering complete
      │
20s   ├─ UI interactive ❌
      │
30s   └─ All features ready

Proposed (Fast) Timeline

0s    ├─ App starts
      │
0.5s  ├─ Network request sent
      │
1s    ├─ Server processing (loadVaultMetadataOnly)
      │
1.5s  ├─ Server response received
      │
2s    ├─ Network transfer complete
      │
2.5s  ├─ Client parsing complete
      │
3s    ├─ UI rendering complete
      │
4s    ├─ UI interactive ✅
      │
      └─ User clicks note
      
4.5s  ├─ Network request sent
      │
5s    ├─ Server processing (single file)
      │
5.5s  ├─ Server response received
      │
6s    ├─ Network transfer complete
      │
6.5s  ├─ Client parsing complete
      │
7s    └─ Note displayed ✅

Component Architecture

Current Architecture

┌─────────────────────────────────────────────────────────────┐
│ AppComponent                                                │
├─────────────────────────────────────────────────────────────┤
│ ├─ VaultService                                             │
│ │  └─ allNotes: Note[] (ALL with content)                   │
│ │                                                           │
│ ├─ AppShellNimbusLayoutComponent                            │
│ │  ├─ NotesListComponent                                    │
│ │  │  └─ Renders all notes (with virtual scroll)            │
│ │  ├─ NoteViewerComponent                                   │
│ │  │  └─ Shows selected note                                │
│ │  └─ FileExplorerComponent                                 │
│ │     └─ Shows file tree                                    │
│ │                                                           │
│ └─ Other components...                                      │
│                                                             │
│ Issue: All notes loaded at startup ❌                        │
└─────────────────────────────────────────────────────────────┘

Proposed Architecture

┌─────────────────────────────────────────────────────────────┐
│ AppComponent                                                │
├─────────────────────────────────────────────────────────────┤
│ ├─ VaultService                                             │
│ │  ├─ allNotesMetadata: Note[] (metadata only)              │
│ │  └─ ensureNoteContent(noteId): Promise<Note>              │
│ │     └─ Lazy load content on-demand                        │
│ │                                                           │
│ ├─ AppShellNimbusLayoutComponent                            │
│ │  ├─ NotesListComponent                                    │
│ │  │  └─ Renders metadata (fast)                            │
│ │  ├─ NoteViewerComponent                                   │
│ │  │  └─ Loads content on-demand                            │
│ │  └─ FileExplorerComponent                                 │
│ │     └─ Shows file tree (from metadata)                    │
│ │                                                           │
│ └─ Other components...                                      │
│                                                             │
│ Benefit: Fast startup + on-demand loading ✅                │
└─────────────────────────────────────────────────────────────┘

Request/Response Comparison

Current: /api/vault

REQUEST:
GET /api/vault HTTP/1.1

RESPONSE:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 5242880

{
  "notes": [
    {
      "id": "note-1",
      "title": "Note 1",
      "content": "# Note 1\n\nLong markdown content...",
      "tags": ["tag1", "tag2"],
      "filePath": "folder/note-1.md",
      "originalPath": "folder/note-1",
      "fileName": "note-1.md",
      "createdAt": "2025-01-01T00:00:00Z",
      "updatedAt": "2025-01-01T00:00:00Z",
      "mtime": 1234567890,
      "frontmatter": { "key": "value" }
    },
    // ... 999 more notes with full content
  ]
}

Size: 5-10 MB ❌
Time: 5-10 seconds ❌

Proposed: /api/vault/metadata

REQUEST:
GET /api/vault/metadata HTTP/1.1

RESPONSE:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 524288

[
  {
    "id": "note-1",
    "title": "Note 1",
    "filePath": "folder/note-1.md",
    "createdAt": "2025-01-01T00:00:00Z",
    "updatedAt": "2025-01-01T00:00:00Z"
  },
  // ... 999 more notes with metadata only
]

Size: 0.5-1 MB ✅
Time: < 1 second ✅

On-Demand: /api/files?path=...

REQUEST:
GET /api/files?path=folder/note-1.md HTTP/1.1

RESPONSE:
HTTP/1.1 200 OK
Content-Type: text/markdown
Content-Length: 5120

# Note 1

Long markdown content...

Size: 5-50 KB ✅
Time: < 500ms ✅

Scaling Comparison

Current Architecture Scaling

Files    Startup Time    Memory    Network
────────────────────────────────────────────
100      2-3s            50MB      500KB
500      8-12s           150MB     2.5MB
1000     15-30s          300MB     5MB
5000     60-120s         1.5GB     25MB ❌
10000    120-240s        3GB       50MB ❌

Problem: Exponential growth ❌

Proposed Architecture Scaling

Files    Startup Time    Memory    Network
────────────────────────────────────────────
100      0.5-1s          10MB      50KB
500      1-2s            30MB      250KB
1000     2-4s            60MB      500KB
5000     3-5s            200MB     2.5MB ✅
10000    4-6s            300MB     5MB ✅

Benefit: Linear growth ✅

Summary

Metric Current Proposed Improvement
Startup Time 15-30s 2-4s 75% faster
Network Payload 5-10MB 0.5-1MB 90% smaller
Memory Usage 200-300MB 50-100MB 75% less
Time to Interactive 20-35s 3-5s 80% faster
Max Files ~5000 Unlimited Unlimited
Complexity High Medium Simpler

Conclusion: The proposed metadata-first architecture provides dramatic improvements in performance, scalability, and user experience with minimal complexity.