diff --git a/packages/docusaurus-theme-mermaid/src/client/index.ts b/packages/docusaurus-theme-mermaid/src/client/index.ts index 8e86fc6c45..51a143387e 100644 --- a/packages/docusaurus-theme-mermaid/src/client/index.ts +++ b/packages/docusaurus-theme-mermaid/src/client/index.ts @@ -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 { - await ensureLayoutsRegistered(); + const mermaid = await loadMermaid(); /* Mermaid API is really weird :s diff --git a/packages/docusaurus-theme-mermaid/src/client/layouts.ts b/packages/docusaurus-theme-mermaid/src/client/loadMermaid.ts similarity index 59% rename from packages/docusaurus-theme-mermaid/src/client/layouts.ts rename to packages/docusaurus-theme-mermaid/src/client/loadMermaid.ts index 25a26d1501..47a6c7b3e8 100644 --- a/packages/docusaurus-theme-mermaid/src/client/layouts.ts +++ b/packages/docusaurus-theme-mermaid/src/client/loadMermaid.ts @@ -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 { + 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 { - if (!layoutsRegistered) { - await registerOptionalElkLayout(); - layoutsRegistered = true; +let MermaidPromise: Promise | 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 { + if (!MermaidPromise) { + MermaidPromise = loadMermaidAndRegisterLayouts(); } + return MermaidPromise; }