Conversation
Enable rendering of mermaid diagrams in markdown preview, allowing users to
create flowcharts, sequence diagrams, and other visualizations directly in
markdown files using standard mermaid syntax.
- Added `ParsedMarkdownMermaidDiagram` element type to handle mermaid code blocks
- Created `mermaid_renderer` module that uses @mermaid-js/mermaid-cli (v11.4.0)
- Integrated async rendering pipeline into markdown preview workflow
- Renders diagrams as high-resolution PNG (2x scale) with transparent background
- Automatically installs mermaid-cli via npm on first use
```mermaid
flowchart TD
A[Markdown File] --> B{Parser}
B -->|```mermaid| C[ParsedMarkdownMermaidDiagram]
B -->|Other blocks| D[Other Elements]
C --> E[Async Render Pipeline]
E --> F[Get NodeRuntime]
F --> G[Install mermaid-cli]
G --> H[Execute mmdc]
H --> I[Generate PNG]
I --> J[Display in Preview]
D --> J
Technical Details
Modified files:
- crates/markdown_preview/src/markdown_elements.rs - New diagram element type
- crates/markdown_preview/src/markdown_parser.rs - Detect mermaid blocks
- crates/markdown_preview/src/markdown_renderer.rs - Render diagram images
- crates/markdown_preview/src/mermaid_renderer.rs - New: mermaid integration
- crates/markdown_preview/src/markdown_preview_view.rs - Async rendering pipeline
- crates/markdown_preview/src/markdown_preview.rs - Module declaration
- crates/markdown_preview/Cargo.toml - Added dependencies
Rendering options:
- Theme: neutral (for clean, simple output)
- Background: transparent (adapts to light/dark themes)
- Scale: 2x (high-resolution for retina displays)
- Format: PNG (universal compatibility)
Cross-Platform Support
Works on macOS, Windows, and Linux. Linux users may need additional system
packages for Puppeteer (libx11-xcb1, libxcomposite1, etc.).
Example Usage
```mermaid
graph LR
A[Start] --> B[Process]
B --> C[End]
```
|
We require contributors to sign our Contributor License Agreement, and we don't have @oscarvarto on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'. |
|
@cla-bot check |
|
The cla-bot has been summoned, and re-checked this pull request! |
|
Yesterday I worked so much that today I need a break. Will revisit this probably next weekend |
…e scaling
Add intelligent content-aware caching and parallel rendering to dramatically
improve performance when editing markdown files with mermaid diagrams. Also
introduce configurable per-diagram scaling via fence syntax.
- Compute hash of diagram content + scale to detect changes
- Only re-render diagrams whose content actually changed
- Cache rendered PNGs with LRU eviction (max 50 diagrams)
- Reuse cached diagrams instantly when content unchanged
**Performance impact:**
- Editing non-mermaid content: 0 diagrams re-rendered (instant updates)
- Editing one diagram: only that diagram re-renders (~1s vs 5-10s before)
- Switching between cached content: instant retrieval
- Render multiple diagrams concurrently using `futures::future::join_all`
- 2-3x faster for documents with multiple diagrams
- Each diagram renders in independent background task
Users can now specify scale percentage in the code fence:
````markdown
```mermaid 50
graph LR
A --> B
flowchart TD
Start --> End
**Syntax:** ` ```mermaid [scale] ` where scale is 10-500 (default: 100)
**Scale calculation:**
- `50` → scale factor 1 (50% of retina default)
- `100` → scale factor 2 (default retina)
- `150` → scale factor 3 (1.5x larger)
- `200` → scale factor 4 (2x larger)
**Smart caching:** Different scales create separate cache entries, so changing
scale triggers re-render but switching back to previous scale uses cache.
```mermaid
flowchart TD
A[Edit Markdown] --> B{Parser}
B -->|mermaid block| C[Compute Hash]
C --> D{In Cache?}
D -->|Yes + File Exists| E[Reuse Cached PNG]
D -->|No| F[Spawn Render Task]
F --> G[Multiple Tasks in Parallel]
G --> H[Execute mmdc]
H --> I[Save to Cache]
I --> J[Update LRU]
J --> K{Cache > 50?}
K -->|Yes| L[Evict Oldest]
K -->|No| M[Display]
L --> M
E --> M
```
**Modified files:**
- `markdown_elements.rs` - Added `scale: u32` and `content_hash: Option<u64>` fields
- `markdown_parser.rs` - Parse scale from fence syntax, compute content hash
- `markdown_preview_view.rs` - Smart cache with LRU, parallel rendering
- `mermaid_renderer.rs` - Accept scale parameter, use integer for mmdc
- `Cargo.toml` - Added `futures` dependency
**Hash computation:**
```rust
let content_hash = {
let mut hasher = collections::FxHasher::default();
code.hash(&mut hasher);
scale.hash(&mut hasher); // Scale affects hash
hasher.finish()
};
```
**LRU cache eviction:**
- Max cache size: 50 diagrams
- Evicts least recently used entries
- Deletes corresponding PNG files on eviction
**Parallel rendering:**
```rust
let render_tasks: Vec<_> = diagrams_needing_render
.map(|diagram| cx.background_executor().spawn(...))
.collect();
let results = futures::future::join_all(render_tasks).await;
```
**Limits:**
- Minimum: 10% (prevents too-small diagrams)
- Maximum: 500% (prevents excessive memory usage)
- Default: 100% (2x scale factor for retina displays)
**Note:** mermaid-cli requires integer scale values, so:
- Values 10-49 → scale factor 1
- Values 50-99 → scale factor 1
- Values 100-149 → scale factor 2
- Values 150-199 → scale factor 3
- etc.
None. Existing ` ```mermaid ` blocks without scale work exactly as before
(default 100% = scale factor 2).
Test cases to verify:
1. ✅ Edit non-mermaid content → no diagram re-renders
2. ✅ Edit one diagram → only that diagram re-renders
3. ✅ Multiple diagrams → render in parallel
4. ✅ Undo diagram edit → uses cached version
5. ✅ Scale 50, 100, 150, 200 → correct sizes
6. ✅ Change scale → triggers re-render with new hash
7. ✅ Cache exceeds 50 diagrams → LRU eviction works
````markdown
Small flowchart:
```mermaid 50
graph LR
A --> B
```
Normal sequence diagram:
```mermaid
sequenceDiagram
Alice->>Bob: Hello
Bob->>Alice: Hi
```
Large complex diagram:
```mermaid 200
flowchart TD
A[Start] --> B{Decision}
B -->|Yes| C[Process]
B -->|No| D[Skip]
C --> E[End]
D --> E
```
|
@Angelk90: I've addressed the re-rendering issue, it should be working now, with parallel rendering, caching, and scaling. Copying commit message: Optimize mermaid diagram rendering with smart caching and configurable scalingAdd intelligent content-aware caching and parallel rendering to dramatically Performance ImprovementsSmart Content-Based Caching
Performance impact:
Parallel Rendering
Configurable ScalingUsers can now specify scale percentage in the code fence: graph LR
A --> B
Syntax: Scale calculation:
Smart caching: Different scales create separate cache entries, so changing Architectureflowchart TD
A[Edit Markdown] --> B{Parser}
B -->|mermaid block| C[Compute Hash]
C --> D{In Cache?}
D -->|Yes + File Exists| E[Reuse Cached PNG]
D -->|No| F[Spawn Render Task]
F --> G[Multiple Tasks in Parallel]
G --> H[Execute mmdc]
H --> I[Save to Cache]
I --> J[Update LRU]
J --> K{Cache > 50?}
K -->|Yes| L[Evict Oldest]
K -->|No| M[Display]
L --> M
E --> M
Technical DetailsModified files:
Hash computation: let content_hash = {
let mut hasher = collections::FxHasher::default();
code.hash(&mut hasher);
scale.hash(&mut hasher); // Scale affects hash
hasher.finish()
};LRU cache eviction:
Parallel rendering: let render_tasks: Vec<_> = diagrams_needing_render
.map(|diagram| cx.background_executor().spawn(...))
.collect();
let results = futures::future::join_all(render_tasks).await;Scale Parameter DetailsLimits:
Note: mermaid-cli requires integer scale values, so:
Breaking ChangesNone. Existing TestingTest cases to verify:
Example UsageSmall flowchart:
```mermaid 50
graph LR
A --> B
```
Normal sequence diagram:
```mermaid
sequenceDiagram
Alice->>Bob: Hello
Bob->>Alice: Hi
```
Large complex diagram:
```mermaid 200
flowchart TD
A[Start] --> B{Decision}
B -->|Yes| C[Process]
B -->|No| D[Skip]
C --> E[End]
D --> E
``` |
|
@Angelk90 You can customize your diagram with styles, did you know? I appreciate the feedback. A friendlier phrasing like 'could you consider theme support?' would be more appropriate for volunteer work. |
|
Hey, thanks for taking the time to work on this. I think it's not ideal to download an npm JS package for parsing Mermaid during render and include this out of the box. |



Enable rendering of mermaid diagrams in markdown preview, allowing users to create flowcharts, sequence diagrams, and other visualizations directly in markdown files using standard mermaid syntax.
ParsedMarkdownMermaidDiagramelement type to handle mermaid code blocksmermaid_renderermodule that uses @mermaid-js/mermaid-cli (v11.4.0)flowchart TD A[Markdown File] --> B{Parser} B -->|mermaid blocks| C[ParsedMarkdownMermaidDiagram] B -->|Other blocks| D[Other Elements] C --> E[Async Render Pipeline] E --> F[Get NodeRuntime] F --> G[Install mermaid-cli] G --> H[Execute mmdc] H --> I[Generate PNG] I --> J[Display in Preview] D --> JTechnical Details
Modified files:
Rendering options:
Cross-Platform Support
Works on macOS, Windows, and Linux. Linux users may need additional system
packages for Puppeteer (libx11-xcb1, libxcomposite1, etc.).
Example Usage
graph LR A[Start] --> B[Process] B --> C[End]Release Notes: