perf(theme-mermaid): lazy load the Mermaid library (#11438)
Some checks failed
Argos CI / take-screenshots (push) Has been cancelled
Build Hash Router / Build Hash Router (push) Has been cancelled
Canary Release / Publish Canary (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Continuous Releases / Continuous Releases (push) Has been cancelled
E2E Tests / E2E — Yarn v1 (20) (push) Has been cancelled
E2E Tests / E2E — Yarn v1 (20.0) (push) Has been cancelled
E2E Tests / E2E — Yarn v1 (22) (push) Has been cancelled
E2E Tests / E2E — Yarn v1 (24) (push) Has been cancelled
E2E Tests / E2E — Yarn v1 Windows (push) Has been cancelled
E2E Tests / E2E — Yarn Berry (node-modules, -s) (push) Has been cancelled
E2E Tests / E2E — Yarn Berry (node-modules, -st) (push) Has been cancelled
E2E Tests / E2E — Yarn Berry (pnp, -s) (push) Has been cancelled
E2E Tests / E2E — Yarn Berry (pnp, -st) (push) Has been cancelled
E2E Tests / E2E — npm (push) Has been cancelled
E2E Tests / E2E — pnpm (push) Has been cancelled

Co-authored-by: slorber <749374+slorber@users.noreply.github.com>
This commit is contained in:
Sébastien Lorber 2025-09-26 23:29:22 +02:00 committed by GitHub
parent b4cc50a423
commit f89fbae282
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 17 additions and 10 deletions

View File

@ -7,8 +7,7 @@
import {useState, useEffect, useMemo} from 'react';
import {useColorMode, useThemeConfig} from '@docusaurus/theme-common';
import mermaid from 'mermaid';
import {ensureLayoutsRegistered} from './layouts';
import {loadMermaid} from './loadMermaid';
import type {RenderResult, MermaidConfig} from 'mermaid';
import type {ThemeConfig} from '@docusaurus/theme-mermaid';
@ -55,7 +54,7 @@ async function renderMermaid({
text: string;
config: MermaidConfig;
}): Promise<RenderResult> {
await ensureLayoutsRegistered();
const mermaid = await loadMermaid();
/*
Mermaid API is really weird :s

View File

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
import mermaid from 'mermaid';
import type {Mermaid} from 'mermaid';
declare global {
// Global variable provided by bundler DefinePlugin
@ -13,7 +13,9 @@ declare global {
const __DOCUSAURUS_MERMAID_LAYOUT_ELK_ENABLED__: boolean;
}
async function registerOptionalElkLayout() {
async function loadMermaidAndRegisterLayouts(): Promise<Mermaid> {
const mermaid = (await import('mermaid')).default;
// Mermaid does not support ELK layouts by default
// See https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid-layout-elk
// ELK layouts are heavy, so we made it an optional peer dependency
@ -22,13 +24,19 @@ async function registerOptionalElkLayout() {
const elkLayout = (await import('@mermaid-js/layout-elk')).default;
mermaid.registerLayoutLoaders(elkLayout);
}
return mermaid;
}
// Ensure we only try to register layouts once
let layoutsRegistered = false;
export async function ensureLayoutsRegistered(): Promise<void> {
if (!layoutsRegistered) {
await registerOptionalElkLayout();
layoutsRegistered = true;
let MermaidPromise: Promise<Mermaid> | null = null;
// We load Mermaid with a dynamic import to code split / lazy load the library
// It is only called inside a useEffect, so loading can be deferred
// We memoize so that we don't load and register layouts multiple times
export async function loadMermaid(): Promise<Mermaid> {
if (!MermaidPromise) {
MermaidPromise = loadMermaidAndRegisterLayouts();
}
return MermaidPromise;
}