Why Caching

The Problem

In server mode, every page request triggers a full content reload:

┌─────────────────────────────────────────────────────────────────────────────┐
│                         WITHOUT CACHING                                     │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   Request: /docs/getting-started/overview                                   │
│                        │                                                    │
│                        ▼                                                    │
│   ┌──────────────────────────────────────┐                                  │
│   │        loadContent()                 │                                  │
│   │   pattern: '**/*.{md,mdx}'           │                                  │
│   └──────────────────────────────────────┘                                  │
│                        │                                                    │
│                        ▼                                                    │
│   ┌──────────────────────────────────────┐                                  │
│   │     Read ALL markdown files          │  ◄── Disk I/O (slow)             │
│   │     from dynamic_data/data/docs/     │                                  │
│   └──────────────────────────────────────┘                                  │
│                        │                                                    │
│                        ▼                                                    │
│   ┌──────────────────────────────────────┐                                  │
│   │   Parse ALL frontmatter & content    │  ◄── CPU (repeated work)         │
│   │   Extract headings for TOC/outline   │                                  │
│   └──────────────────────────────────────┘                                  │
│                        │                                                    │
│                        ▼                                                    │
│   ┌──────────────────────────────────────┐                                  │
│   │   Build sidebar tree from content    │  ◄── Tree construction           │
│   │   Read settings.json for each folder │      + filesystem reads          │
│   └──────────────────────────────────────┘                                  │
│                        │                                                    │
│                        ▼                                                    │
│   ┌──────────────────────────────────────┐                                  │
│   │   Load theme CSS files               │  ◄── More disk I/O               │
│   │   Resolve theme inheritance          │                                  │
│   └──────────────────────────────────────┘                                  │
│                        │                                                    │
│                        ▼                                                    │
│              Render single page                                             │
│                                                                             │
│   Total: ~150-200ms per request                                             │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Why Full Content Load?

The page handler needs ALL content for several features:

1. Sidebar Navigation

Requires the full content tree to build navigation structure.

// Layout needs all docs for sidebar
const allContent = await loadContent(dataPath, 'docs');
const sidebarNodes = buildSidebarTree(allContent, baseUrl, dataPath);

2. Pagination

Previous/next links require knowing adjacent pages.

// Need full list to find prev/next
const { prev, next } = getPrevNext(sidebarNodes, currentPath);

3. Content Lookup

Finding the requested document by slug.

// Find single page from all content
const doc = allContent.find(d => d.slug === docSlug);

The Cost

Per-Request Work (Without Caching)

Operation Time Impact
Glob all files ~20-30ms Disk I/O
Parse markdown ~50-100ms CPU intensive
Extract headings ~10-20ms Per file
Build sidebar tree ~10-15ms Filesystem reads
Load theme CSS ~5-10ms Disk I/O
Total ~150-200ms Every request

Real-World Impact

10 page navigations without cache:
  10 × 150ms = 1.5 seconds of processing

With 50 docs and 5 themes:
  50 files parsed × 10 requests = 500 parse operations
  All completely redundant after first load

What Needs Caching

┌─────────────────────────────────────────────────────────────────────────────┐
│                     CACHEABLE COMPONENTS                                    │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   1. CONTENT                                                                │
│      ├── Parsed markdown (HTML)                                             │
│      ├── Extracted headings (for TOC/outline)                               │
│      ├── Frontmatter data                                                   │
│      └── File metadata (slug, path)                                         │
│                                                                             │
│   2. SIDEBAR                                                                │
│      ├── Tree structure (sections + items)                                  │
│      ├── Folder settings (collapsed, collapsible)                           │
│      └── Position ordering                                                  │
│                                                                             │
│   3. THEME                                                                  │
│      ├── Theme configuration (manifest)                                     │
│      ├── CSS content                                                        │
│      └── Combined CSS (with inheritance)                                    │
│                                                                             │
│   4. SETTINGS                                                               │
│      ├── Content directory settings                                         │
│      └── Sidebar/outline/pagination config                                  │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Cache Invalidation Challenge

The challenge is knowing WHEN to invalidate:

Change Type What to Invalidate
Edit .md file Content + Sidebar
Add/delete .md file Content + Sidebar
Edit settings.json Sidebar + Settings
Edit theme CSS Theme only
Edit site.yaml Config + Theme

Solution: Selective invalidation based on file type, handled by HMR.


Performance Target

┌─────────────────────────────────────────────────────────────────────────────┐
│                         WITH CACHING                                        │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   FIRST REQUEST (cold)                                                      │
│   └── Full load: ~150-200ms (unavoidable)                                   │
│                                                                             │
│   SUBSEQUENT REQUESTS (warm)                                                │
│   └── Cache hit: ~5ms (97% faster)                                          │
│                                                                             │
│   10 page navigations:                                                      │
│   └── 150ms + (9 × 5ms) = 195ms total                                       │
│       vs 1,500ms without cache                                              │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

See Unified Cache System for the implementation.