Skip to content

perf: lazy-load Mermaid, YouTube, and TwitterTweetEmbed to reduce bundle size - #5667

Open
patilpratik1905 wants to merge 1 commit into
asyncapi:masterfrom
patilpratik1905:perf_enh/mermaid_dynamicImport
Open

perf: lazy-load Mermaid, YouTube, and TwitterTweetEmbed to reduce bundle size#5667
patilpratik1905 wants to merge 1 commit into
asyncapi:masterfrom
patilpratik1905:perf_enh/mermaid_dynamicImport

Conversation

@patilpratik1905

@patilpratik1905 patilpratik1905 commented Jul 30, 2026

Copy link
Copy Markdown

Problem

MDX.tsx was statically importing:

  • mermaid (~1.5 MB)
  • All 10 named exports from react-twitter-embed
  • react-youtube-embed

As a result, these libraries were included in the initial JavaScript bundle for every page using the MDX renderer, even when the page contained no Mermaid diagrams, Twitter embeds, or YouTube videos.

On Lighthouse mobile (4× CPU slowdown), this resulted in several seconds of unnecessary JavaScript parsing and execution, negatively impacting:

  • Total Blocking Time (TBT)
  • Time to Interactive (TTI)
  • Speed Index
  • Largest Contentful Paint (LCP)

Root Cause

MDX.tsx used static imports for Mermaid, Twitter, and YouTube components, preventing webpack from code-splitting these dependencies. Consequently, every MDX page downloaded and parsed these libraries regardless of whether they were actually used.

Solution

Mermaid

  • Extracted the existing Mermaid implementation into a dedicated MermaidDiagram.tsx component.
  • Preserved all existing functionality, including:
    • Mermaid theme variables
    • MutationObserver theme switching
    • mermaidAPI.render logic
  • Replaced the static import with:
dynamic(() => import("./MermaidDiagram"), {
  ssr: false,
});

Twitter Embed

  • Replaced the static named import with a dynamically imported TwitterTweetEmbed:
dynamic(
  () =>
    import("react-twitter-embed").then((mod) => ({
      default: mod.TwitterTweetEmbed,
    })),
  { ssr: false }
);

Remove Unused Twitter Components

Removed the following unused exports:

  • TwitterTimelineEmbed
  • TwitterShareButton
  • TwitterFollowButton
  • TwitterHashtagButton
  • TwitterMentionButton
  • TwitterMomentShare
  • TwitterDMButton
  • TwitterVideoEmbed
  • TwitterOnAirButton

A repository-wide grep across all .mdx files confirmed that none of these components are referenced anywhere in the documentation.

YouTube

Replaced the static import with:

dynamic(() => import("react-youtube-embed"), {
  ssr: false,
});

All dynamic imports use ssr: false because these components rely on browser-only APIs such as document, MutationObserver, and third-party embed scripts.

Testing

  • npx tsc --noEmit
  • npm run lint
  • Verified Mermaid diagrams render correctly
  • Verified Twitter embeds render correctly
  • Verified YouTube embeds render correctly
  • Verified Mermaid light/dark theme switching continues to work

Performance Impact

Metric Before After
Initial JS parsed (MDX pages without diagrams/embeds) +~1.8 MB ~1.8 MB deferred
Pages containing Mermaid Mermaid bundled upfront Mermaid loaded only when required
Pages containing Twitter embeds Twitter library bundled upfront Loaded only when required
Pages containing YouTube embeds YouTube library bundled upfront Loaded only when required
Mobile TBT / TTI High Significantly reduced

Related Issue

Summary by CodeRabbit

  • New Features

    • Added Mermaid diagram rendering with automatic light and dark theme support.
    • Mermaid diagrams now update when the site theme changes.
  • Bug Fixes

    • Improved client-side loading for Mermaid, YouTube, and Twitter embeds.
    • Added stricter diagram rendering security and graceful error handling.

@netlify

netlify Bot commented Jul 30, 2026

Copy link
Copy Markdown

Deploy Preview for asyncapi-website ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit df7de6c
🔍 Latest deploy log https://app.netlify.com/projects/asyncapi-website/deploys/6a6ae6b5a9787d0008bf7bee
😎 Deploy Preview https://deploy-preview-5667--asyncapi-website.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

MDX embeds now use client-only dynamic loading. Mermaid rendering moved into a dedicated component with strict security, light/dark theme variables, theme-change detection, SVG rendering, and error handling.

Changes

MDX embed rendering

Layer / File(s) Summary
Theme-aware Mermaid rendering
components/MDX/MermaidDiagram.tsx
Adds client-side Mermaid rendering with strict security, theme-specific variables, MutationObserver theme tracking, SVG output, and error handling.
Client-only MDX embed wiring
components/MDX/MDX.tsx
Dynamically loads Mermaid, YouTube, and Twitter embeds, updates the exported embed map, and preserves existing MDX renderer behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MDXProvider
  participant MermaidDiagram
  participant MermaidAPI
  MDXProvider->>MermaidDiagram: pass graph
  MermaidDiagram->>MermaidDiagram: detect active theme
  MermaidDiagram->>MermaidAPI: initialize and render graph
  MermaidAPI-->>MermaidDiagram: return SVG
  MermaidDiagram-->>MDXProvider: inject SVG
Loading

Possibly related PRs

Suggested reviewers: akshatnema, sambhavgupta0705, princerajpoot20

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: lazy-loading Mermaid, YouTube, and Twitter embeds to reduce bundle size.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sonarqubecloud

Copy link
Copy Markdown

@asyncapi-bot

Copy link
Copy Markdown
Contributor

⚡️ Lighthouse report for the changes in this PR:

Category Score
🔴 Performance 48
🟢 Accessibility 98
🟢 Best practices 92
🟢 SEO 100
🔴 PWA 33

Lighthouse ran on https://deploy-preview-5667--asyncapi-website.netlify.app/

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/MDX/MermaidDiagram.tsx`:
- Line 25: Apply the repository formatter to the full changed files
components/MDX/MermaidDiagram.tsx (anchor, line 25) and components/MDX/MDX.tsx
(sibling, line 39), correcting trailing commas, dynamic-import formatting, and
JSX layout violations without changing behavior.
- Around line 101-105: Initialize the theme state in MermaidDiagram from
getMermaidTheme() instead of defaulting to 'light', so the first render uses the
active page theme. Update the existing useEffect only as needed to continue
responding to later theme changes.
- Line 3: Upgrade the Mermaid dependency used by the MermaidDiagram renderer to
a fixed release newer than 9.3.0, then regression-test client-side MDX graph
rendering, including relevant graph and Gantt diagrams. Preserve the existing
import and rendering behavior while confirming the upgrade prevents the reported
CSS injection and Gantt loop issues.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 96d003fe-c720-45dc-8645-4ca791620693

📥 Commits

Reviewing files that changed from the base of the PR and between 22287b1 and df7de6c.

📒 Files selected for processing (2)
  • components/MDX/MDX.tsx
  • components/MDX/MermaidDiagram.tsx

@@ -0,0 +1,150 @@
'use client';

import mermaid from 'mermaid';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)components/MDX/MermaidDiagram\.tsx$|package\.json$|package-lock\.json$|pnpm-lock\.yaml$|yarn\.lock$' || true

echo "== MermaidDiagram excerpt =="
if [ -f components/MDX/MermaidDiagram.tsx ]; then
  wc -l components/MDX/MermaidDiagram.tsx
  sed -n '1,160p' components/MDX/MermaidDiagram.tsx | cat -n
fi

echo "== package mermaid references =="
for f in package.json package-lock.json pnpm-lock.yaml yarn.lock; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    rg -n '"?mermaid"?|mermaid@|mermaid:' "$f" -A 3 -B 3 || true
  fi
done

echo "== mermaid imports/usages =="
rg -n "mermaid|Mermaid" . --glob '!node_modules' --glob '!dist' --glob '!build' || true

Repository: asyncapi/website

Length of output: 16356


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read-only package-management/dependency verifier: inspect exact mermaid package versions
# declared in lock metadata when available, without installing or running repo code.
python3 - <<'PY'
import json, re, pathlib

def parse_package_json(p):
    data=json.loads(p.read_text())
    for section in ["dependencies","devDependencies","optionalDependencies","peerDependencies"]:
        if section in data:
            for name,val in data[section].items():
                if name.lower()=="mermaid":
                    print("package.json", section, name, val)

for lock in ["package-lock.json","pnpm-lock.yaml","yarn.lock"]:
    p=pathlib.Path(lock)
    if not p.exists(): continue
    print(f"LOCK {lock}")
    text=p.read_text(errors="ignore")
    if lock == "package-lock.json":
        data=json.loads(text)
        packages=data.get("packages", {})
        for pkg, meta in packages.items():
            if pkg in ("", "node_modules/mermaid"):
                continue
            if "mermaid" in pkg.lower():
                ver=meta.get("version")
                pkg_path=pkg.replace("\\","/")
                print(pkg_path, "version=", ver, "dependencies=", meta.get("dependencies"))
    elif lock == "pnpm-lock.yaml":
        for line in text.splitlines():
            m=re.search(r'^\s*(?:mermaid[^:\s]*)?:\s*(?:version:\s*)?(\S+)', line)
            if m:
                print("pnpm_lock", m.group(1))
        if "mermaid:" in text:
            idx=text.find("\n  mermaid:")
            print(text[idx:idx+400])
    elif lock == "yarn.lock":
        for m in re.finditer(r'^"mermaid@[^"]*":\s*\r?\n((?:[^\n]+(?:\r?\n|(?<!\r)\n))*?)\n([A-Z]|\s*(?:[^"][A-Za-z0-9_/\-@]|"))', text, re.S):
            block="\n".join(m.group(1).splitlines())
            ver_match=re.search(r'version "([^"]+)"', block)
            print("yarn_lock", ver_match.group(1) if ver_match else block.splitlines()[0])

PY

Repository: asyncapi/website

Length of output: 177


🌐 Web query:

Mermaid 9.3.0 affected vulnerabilities CSS injection Gantt infinite loop securityLevel strict

💡 Result:

Mermaid version 9.3.0 is affected by various security vulnerabilities, as it precedes the fixed versions (10.9.6 and 11.15.0) that address multiple recently identified flaws [1][2][3]. Regarding the specific issues mentioned: CSS Injection: Recent vulnerabilities (e.g., CVE-2026-41159 and others) involve improper sanitization of configuration options (like fontFamily, themeCSS, and altFontFamily) and classDef directives [1][4][3]. These flaws allow attackers to inject malicious CSS that can escape the diagram's scope, leading to page defacement or data exfiltration [1][3]. Gantt Infinite Loop: A denial-of-service (DoS) vulnerability (CVE-2026-41150) affects Mermaid Gantt charts when they use an 'excludes' attribute to exclude all dates, causing an infinite loop during rendering [2][5][6]. SecurityLevel Strict: Setting 'securityLevel' to 'strict' is a standard security practice in Mermaid that encodes HTML tags and disables click functionality [7][8]. However, it may not fully mitigate all injection vulnerabilities depending on the specific attack vector (e.g., configuration-based CSS injection) [1][3]. For the highest level of security when rendering untrusted content, the 'sandbox' securityLevel is recommended, as it renders the diagram within a sandboxed iframe [1][3][8]. To secure your application, you should upgrade to version 10.9.6 or 11.15.0 or later [1][2][3]. If upgrading is not immediately possible, using 'securityLevel': 'sandbox' is the suggested mitigation for several of these injection-based vulnerabilities [1][3][9].

Citations:


🌐 Web query:

mermaid 10.9.6 release notes vulnerabilities fixed

💡 Result:

The Mermaid 10.9.6 release, published on May 11, 2026, includes backported security fixes originally addressed in version 11.15.0 [1][2]. This release resolves several vulnerabilities and dependency issues [1]: Security Fixes - CVE-2026-41159 (GHSA-87f9-hvmw-gh4p): Fixed an improper sanitization issue in configuration options (fontFamily, themeCSS, and altFontFamily) that allowed for CSS injection and escaping of diagram scoping [3][4]. - CVE-2026-41148: Prevented unbalanced CSS styles in classDefs [1][5]. - CVE-2026-41149: Updated the creation of CSS styles to utilize the CSSOM (CSS Object Model) [1][5]. - CVE-2026-41150: Fixed a potential infinite loop in the Gantt diagram implementation when excluding all dates [1][5]. Dependency and Other Fixes - CVE-2026-41907: Loosened the uuid dependency range to allow version 14. This change allows users to silence dependency warnings for a vulnerable code path that Mermaid does not actively use [1][5]. For systems unable to upgrade immediately, the CSS injection vulnerability (CVE-2026-41159) can be mitigated by setting the securityLevel configuration to 'sandbox' or by enabling the secure configuration option [3][4].

Citations:


Upgrade Mermaid before rendering MDX graphs client-side.

The app pins Mermaid 9.3.0, which is affected by later-fixed CSS injection and Gantt infinite-loop vulnerabilities that can alter page styling or hang a visiting tab. Upgrade to a fixed release and regression-test the renderer.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/MDX/MermaidDiagram.tsx` at line 3, Upgrade the Mermaid dependency
used by the MermaidDiagram renderer to a fixed release newer than 9.3.0, then
regression-test client-side MDX graph rendering, including relevant graph and
Gantt diagrams. Preserve the existing import and rendering behavior while
confirming the upgrade prevents the reported CSS injection and Gantt loop
issues.

tertiaryBkg: '#F7F9FA',
clusterBkg: '#F7F9FA',
clusterBorder: '#BFC6C7',
edgeLabelBackground: '#FFFFFF',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Apply the repository formatter to both changed files.

The supplied ESLint results report Prettier errors throughout both files.

  • components/MDX/MermaidDiagram.tsx#L25-L25: format the full changed file, including trailing-comma violations.
  • components/MDX/MDX.tsx#L39-L39: format the full changed file, including dynamic-import and JSX layout violations.
🧰 Tools
🪛 ESLint

[error] 25-25: Delete ,

(prettier/prettier)

📍 Affects 2 files
  • components/MDX/MermaidDiagram.tsx#L25-L25 (this comment)
  • components/MDX/MDX.tsx#L39-L39
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/MDX/MermaidDiagram.tsx` at line 25, Apply the repository formatter
to the full changed files components/MDX/MermaidDiagram.tsx (anchor, line 25)
and components/MDX/MDX.tsx (sibling, line 39), correcting trailing commas,
dynamic-import formatting, and JSX layout violations without changing behavior.

Source: Linters/SAST tools

Comment on lines +101 to +105
const [svg, setSvg] = useState<string | null>(null);
const [theme, setTheme] = useState<MermaidTheme>('light');

useEffect(() => {
setTheme(getMermaidTheme());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick win

Initialize from the active theme.

On an initially dark page, the first render effect always renders a light diagram, then re-renders it dark after setTheme. This doubles Mermaid layout work and can briefly show the wrong theme.

Proposed fix
 const [svg, setSvg] = useState<string | null>(null);
-const [theme, setTheme] = useState<MermaidTheme>('light');
+const [theme, setTheme] = useState<MermaidTheme>(getMermaidTheme);

 useEffect(() => {
-  setTheme(getMermaidTheme());
-
   const observer = new MutationObserver(() => {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const [svg, setSvg] = useState<string | null>(null);
const [theme, setTheme] = useState<MermaidTheme>('light');
useEffect(() => {
setTheme(getMermaidTheme());
const [svg, setSvg] = useState<string | null>(null);
const [theme, setTheme] = useState<MermaidTheme>(getMermaidTheme);
useEffect(() => {
const observer = new MutationObserver(() => {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/MDX/MermaidDiagram.tsx` around lines 101 - 105, Initialize the
theme state in MermaidDiagram from getMermaidTheme() instead of defaulting to
'light', so the first render uses the active page theme. Update the existing
useEffect only as needed to continue responding to later theme changes.

@github-actions github-actions Bot added the bounty AsyncAPI Bounty program related label label Jul 31, 2026
@aeworxet

Copy link
Copy Markdown
Contributor

@asyncapi/bounty_team

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bounty AsyncAPI Bounty program related label

Projects

Status: In Progress
Status: To Be Triaged

Development

Successfully merging this pull request may close these issues.

[FEATURE] Performance + Accessibility Improvement of website

3 participants