From f89fbae2823510b7e4c3a7ef7e854740d7c33402 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lorber?= Date: Fri, 26 Sep 2025 23:29:22 +0200 Subject: [PATCH] perf(theme-mermaid): lazy load the Mermaid library (#11438) Co-authored-by: slorber <749374+slorber@users.noreply.github.com> --- .../src/client/index.ts | 5 ++--- .../src/client/{layouts.ts => loadMermaid.ts} | 22 +++++++++++++------ 2 files changed, 17 insertions(+), 10 deletions(-) rename packages/docusaurus-theme-mermaid/src/client/{layouts.ts => loadMermaid.ts} (59%) 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; }