Open bheads opened 3 years ago
@bheads Mermaid's rendering uses the DOM (through the D3.js library)
There's a proof of concept of moving D3-based SVG generation to web workers that might work https://github.com/chrisahardie/d3-svg-chart-in-web-worker
Quick glance through Gantt chart rendering code leaves me thinking there should be little to no errors if you'd try to use in inside jsdom
context. Didn't try it though.
https://github.com/mermaid-js/mermaid/blob/develop/src/diagrams/gantt/ganttRenderer.js
@knsv sorry for the mention, are you aware of any successful attempt at running mermaid in a worker? I need to move mermaid out of my main thread for security and performance isolation.
What about moving it to an iframe? As far as I can tell you can do your rendering in there using the normal DOM API and then just transfer the resulting svg string back.
I just tested this in a Proof of Concept in a SvelteKit app:
<script lang="ts">
import { onMount } from "svelte";
import mermaid from 'mermaid';
let logContainer: HTMLUListElement;
function log(message: string) {
const line = document.createElement('li');
line.innerText = message;
logContainer.append(line);
}
onMount(() => {
const channel = new BroadcastChannel('mermaid');
channel.addEventListener('message', async (ev) => {
log(ev.data);
const result = await mermaid.render('test', ev.data);
channel.postMessage(result.svg);
})
})
</script>
This is a worker, we load it in an iframe for now.
<ul bind:this={logContainer}>
</ul>
This is a trivial and ugly implementation. It listens for diagram strings on a broadcast channel and sends back svg strings on the same channel. It will probably hard crash if you open multiple tabs with this code.
But... it works and should even be trivial to scale.
Is your feature request related to a problem? Please describe. Our internal app often generates large graphs, it would be nice to run the render in a web work to not lock up the page.
Describe the solution you'd like Support rendering in a web worker