Keeping diagrams off the critical path#
Sumi's promise is that heavy scripts load only where they are used. For Mermaid that was true, but not enough: a page with one diagram scored 45 in Lighthouse's mobile test, and its largest paint arrived after 10 seconds.
What was slow#
Mermaid shipped as one 5.5 MB script (1.5 MB compressed). On a page with a diagram, Sumi fetched it as soon as the page opened. Parsing that much JavaScript on a throttled phone CPU blocks everything else, and the diagram's own text was the largest element on screen, so the page "finished" only once Mermaid did.
What changed#
- Mermaid is split by diagram type. Sumi now ships Mermaid's ES module build. A page with a flowchart fetches Mermaid's core and the flowchart code; the code for Gantt charts, mind maps and the other twenty diagram types stays on the server.
- Nothing loads until a diagram is near. Each diagram is watched, and Mermaid is fetched when the first one comes within 400 pixels of the viewport. A diagram at the bottom of a long page costs nothing until the reader scrolls to it.
- One diagram at a time. Diagrams render in sequence instead of all at once, so the main thread gets breaks in between.
Until a diagram is drawn, readers see its source text, which is also what readers without JavaScript see.
Before and after#
| Diagrams page, Lighthouse mobile | Before | After |
|---|---|---|
| Performance score | 35 | 73 |
| Largest contentful paint | 31.0 s | 2.3 s |
| JavaScript downloaded | 5.4 MB | 2.4 MB |
Pages without diagrams were already at 94–100 and are unchanged.
While we were there#
Every drawn diagram now has three buttons: open it full screen, copy its Mermaid source, and download it as an SVG file. And two more text-to-picture fences arrived, built the same way: charts with Apache ECharts and mind maps with Markmap.
Note
ES modules cannot be loaded from file:// pages. Serve the built site, even locally with python -m http.server, to see diagrams.