diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml new file mode 100644 index 00000000..218302f6 --- /dev/null +++ b/.github/workflows/benchmark.yml @@ -0,0 +1,36 @@ +name: Run Benchmarks. + +# publish only when package json has changed - assuming version upgrade +on: + workflow_dispatch: + +jobs: + publish: + if: github.event.repository.owner.login == 'md2docx' + runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + + steps: + - uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/setup-node@v4 + with: + node-version: 20 + registry-url: https://registry.npmjs.org + - name: Setup Git + run: | + git config --global user.name "mayank1513" + git config --global user.email "mayank.srmu@gmail.com" + - run: npm i -g pnpm && pnpm i + name: Install dependencies + - name: clean up working directory + run: git status && git clean -f -d && git status + + - name: Run Benchmarks + run: cd lib && pnpm build && pnpm benchmark + - name: Save benchmarks back to repo + run: git add . && git commit -m "Update benchmarks" && git push diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3bdf823b..c21aba0f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -36,7 +36,7 @@ jobs: run: pnpm test working-directory: ./lib - name: Copy Readme file - run: cp ./README.md ./lib # will be uncommented while rebranding + run: cp ./README.md ./lib - name: Apply changesets, publish and create release, branches and tags run: node ./scripts/publish.js env: diff --git a/README.md b/README.md index 8a61bfde..a359670f 100644 --- a/README.md +++ b/README.md @@ -111,12 +111,15 @@ export default function Page() { Unlike most markdown renderers, `@m2d/react-markdown` supports **arbitrary JSX as children**: ```tsx - +import { Mdx } from "@m2d/react-markdown/server"; +// ... + {"# Markdown Heading\n\nSome **rich** content."} - +; ``` > `astRef.current` is an array — one per Markdown string — each with `{ mdast, hast }`. +> The default `` export accepts only string children for better optimization. --- diff --git a/benchmark-logs/benchmark.json b/benchmark-logs/benchmark.json new file mode 100644 index 00000000..0b779286 --- /dev/null +++ b/benchmark-logs/benchmark.json @@ -0,0 +1,419 @@ +{ + "no": { + "sample.md": [ + { + "name": "@m2d/react-markdown", + "ops": 42.74708438167588, + "margin": 3.1493983894881623 + }, + { + "name": "react-markdown", + "ops": 42.98277392923757, + "margin": 2.5108926226895676 + } + ], + "short.md": [ + { + "name": "@m2d/react-markdown", + "ops": 1531.3757006079813, + "margin": 4.087216414945013 + }, + { + "name": "react-markdown", + "ops": 1851.9390643331176, + "margin": 2.8258801868390995 + } + ], + "medium.md": [ + { + "name": "@m2d/react-markdown", + "ops": 286.5658635012855, + "margin": 4.248816163584699 + }, + { + "name": "react-markdown", + "ops": 276.00747808036925, + "margin": 4.365476215061842 + } + ], + "long.md": [ + { + "name": "@m2d/react-markdown", + "ops": 20.635262930563872, + "margin": 4.371644878505462 + }, + { + "name": "react-markdown", + "ops": 18.792480150335255, + "margin": 4.886883318740262 + } + ], + "short-simple.md": [ + { + "name": "@m2d/react-markdown", + "ops": 975.2144674133882, + "margin": 3.63220674044318 + }, + { + "name": "react-markdown", + "ops": 983.5741252107894, + "margin": 3.135455816598657 + } + ], + "medium-formatting.md": [ + { + "name": "@m2d/react-markdown", + "ops": 611.6894985569703, + "margin": 3.013959035373157 + }, + { + "name": "react-markdown", + "ops": 645.4271527261262, + "margin": 2.2518994079362176 + } + ], + "long-tutorial.md": [ + { + "name": "@m2d/react-markdown", + "ops": 390.723965985505, + "margin": 2.798733891444964 + }, + { + "name": "react-markdown", + "ops": 361.5177777014237, + "margin": 2.521911127523275 + } + ], + "gfm-complexity.md": [ + { + "name": "@m2d/react-markdown", + "ops": 771.5341523280497, + "margin": 3.479259467012237 + }, + { + "name": "react-markdown", + "ops": 825.411461792101, + "margin": 2.337091485889471 + } + ], + "deeply-nested-lists.md": [ + { + "name": "@m2d/react-markdown", + "ops": 614.4103650712425, + "margin": 3.3878555809063218 + }, + { + "name": "react-markdown", + "ops": 634.6825328027951, + "margin": 3.0217868410897615 + } + ], + "site-content.md": [ + { + "name": "@m2d/react-markdown", + "ops": 640.2005588716024, + "margin": 2.687020064360469 + }, + { + "name": "react-markdown", + "ops": 649.7068546260045, + "margin": 2.2689517784718953 + } + ], + "All files": [ + { + "name": "react-markdown", + "ops": 10.928697086284455, + "margin": 3.8318922533268456 + }, + { + "name": "@m2d/react-markdown", + "ops": 11.361060403806082, + "margin": 3.6759820409301156 + }, + { + "name": "@m2d/react-markdown as nested jsx", + "ops": 11.180671352284898, + "margin": 3.787295962068112 + } + ] + }, + "remark-gfm, remark-math, and remark-frontmatter": { + "sample.md": [ + { + "name": "@m2d/react-markdown", + "ops": 29.082675958339877, + "margin": 2.156768616953331 + }, + { + "name": "react-markdown", + "ops": 27.866921662269842, + "margin": 1.854725697011497 + } + ], + "short.md": [ + { + "name": "@m2d/react-markdown", + "ops": 983.1686946675665, + "margin": 1.3743912669953593 + }, + { + "name": "react-markdown", + "ops": 1074.7174608421187, + "margin": 1.3496359984490789 + } + ], + "medium.md": [ + { + "name": "@m2d/react-markdown", + "ops": 184.12467512549756, + "margin": 2.9066671032211078 + }, + { + "name": "react-markdown", + "ops": 178.4132210116435, + "margin": 2.8084319185668463 + } + ], + "long.md": [ + { + "name": "@m2d/react-markdown", + "ops": 16.564404801792207, + "margin": 3.587871940116675 + }, + { + "name": "react-markdown", + "ops": 15.800009201624405, + "margin": 3.5291895862957707 + } + ], + "short-simple.md": [ + { + "name": "@m2d/react-markdown", + "ops": 598.6925479890702, + "margin": 1.2821149562725644 + }, + { + "name": "react-markdown", + "ops": 631.3869509982479, + "margin": 1.1811170152416268 + } + ], + "medium-formatting.md": [ + { + "name": "@m2d/react-markdown", + "ops": 426.9162928299208, + "margin": 1.1355042985631263 + }, + { + "name": "react-markdown", + "ops": 200.0710934220817, + "margin": 7.839700450385986 + } + ], + "long-tutorial.md": [ + { + "name": "@m2d/react-markdown", + "ops": 193.31801041845242, + "margin": 9.921574753902991 + }, + { + "name": "react-markdown", + "ops": 235.68832089226325, + "margin": 1.5726928647003986 + } + ], + "gfm-complexity.md": [ + { + "name": "@m2d/react-markdown", + "ops": 414.0911487677954, + "margin": 2.995465126627123 + }, + { + "name": "react-markdown", + "ops": 418.03644605120616, + "margin": 2.5047022830882675 + } + ], + "deeply-nested-lists.md": [ + { + "name": "@m2d/react-markdown", + "ops": 415.2958547344348, + "margin": 1.7030721973907024 + }, + { + "name": "react-markdown", + "ops": 411.9566502056854, + "margin": 1.8086609089084258 + } + ], + "site-content.md": [ + { + "name": "@m2d/react-markdown", + "ops": 445.8356188710065, + "margin": 1.2457920642045548 + }, + { + "name": "react-markdown", + "ops": 457.94329696482714, + "margin": 1.410380300104795 + } + ], + "All files": [ + { + "name": "react-markdown", + "ops": 8.174038243682, + "margin": 3.1491059579188705 + }, + { + "name": "@m2d/react-markdown", + "ops": 7.916570700995681, + "margin": 3.334001090104863 + }, + { + "name": "@m2d/react-markdown as nested jsx", + "ops": 8.10126172088014, + "margin": 2.896125605566574 + } + ] + }, + "remark-gfm, and rehype-raw": { + "sample.md": [ + { + "name": "@m2d/react-markdown", + "ops": 24.17786223599516, + "margin": 1.9381887247422778 + }, + { + "name": "react-markdown", + "ops": 24.55039890014213, + "margin": 1.485019112819352 + } + ], + "short.md": [ + { + "name": "@m2d/react-markdown", + "ops": 870.7057124894626, + "margin": 1.4584309203699772 + }, + { + "name": "react-markdown", + "ops": 1031.1096191025754, + "margin": 1.1416735228392947 + } + ], + "medium.md": [ + { + "name": "@m2d/react-markdown", + "ops": 162.7275824271953, + "margin": 2.5628139840352153 + }, + { + "name": "react-markdown", + "ops": 164.37514683723185, + "margin": 2.444595974095591 + } + ], + "long.md": [ + { + "name": "@m2d/react-markdown", + "ops": 14.424855249949237, + "margin": 3.5577466182169335 + }, + { + "name": "react-markdown", + "ops": 14.019699516469753, + "margin": 3.403465493485481 + } + ], + "short-simple.md": [ + { + "name": "@m2d/react-markdown", + "ops": 554.7798697813188, + "margin": 1.0263647939516976 + }, + { + "name": "react-markdown", + "ops": 578.7042068259314, + "margin": 1.4260338597432547 + } + ], + "medium-formatting.md": [ + { + "name": "@m2d/react-markdown", + "ops": 402.9810377580538, + "margin": 1.072016811761951 + }, + { + "name": "react-markdown", + "ops": 422.1711023602763, + "margin": 1.084320507025387 + } + ], + "long-tutorial.md": [ + { + "name": "@m2d/react-markdown", + "ops": 212.73842839589844, + "margin": 1.2979512510074058 + }, + { + "name": "react-markdown", + "ops": 212.08201139689257, + "margin": 1.1788314524242725 + } + ], + "gfm-complexity.md": [ + { + "name": "@m2d/react-markdown", + "ops": 375.09715543283266, + "margin": 2.091377602129898 + }, + { + "name": "react-markdown", + "ops": 384.92039307308175, + "margin": 1.7916669054496637 + } + ], + "deeply-nested-lists.md": [ + { + "name": "@m2d/react-markdown", + "ops": 264.7146944640334, + "margin": 8.586728468108886 + }, + { + "name": "react-markdown", + "ops": 392.5829796542143, + "margin": 1.1554806485327342 + } + ], + "site-content.md": [ + { + "name": "@m2d/react-markdown", + "ops": 411.9572994318351, + "margin": 1.3718092923871366 + }, + { + "name": "react-markdown", + "ops": 435.0696872059333, + "margin": 1.3077531830422384 + } + ], + "All files": [ + { + "name": "react-markdown", + "ops": 7.222618931254631, + "margin": 2.5866003742238086 + }, + { + "name": "@m2d/react-markdown", + "ops": 7.460295281142587, + "margin": 2.978680775521445 + }, + { + "name": "@m2d/react-markdown as nested jsx", + "ops": 5.052434356222568, + "margin": 12.555713427904202 + } + ] + } +} \ No newline at end of file diff --git a/benchmark-logs/benchmark.md b/benchmark-logs/benchmark.md new file mode 100644 index 00000000..c105a02f --- /dev/null +++ b/benchmark-logs/benchmark.md @@ -0,0 +1,315 @@ +# 📊 Markdown Render Benchmark + +🧠 System Info + +- **platform:** win32 +- **arch:** x64 +- **cpu:** 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz +- **cores:** 8 +- **node:** v20.10.0 +- **memory:** 15.79 GB +- **Benchmark time:** Sat Jul 12 2025 01:17:07 GMT+0530 (India Standard Time) + + +## Benchmarks with no plugins. + +~~~mermaid +xychart-beta + title "Render Speed Comparison (Ops/sec)" + x-axis ["short.md", "medium.md", "long.md", "All files"] + y-axis "Ops/sec (higher is better)" + bar [1851.9390643331176, 276.00747808036925, 18.792480150335255, 10.928697086284455] %% react-markdown + bar [1531.3757006079813, 286.5658635012855, 20.635262930563872, 11.361060403806082] %% @m2d/react-markdown +~~~ + +~~~mermaid +xychart-beta + title "Render Speed Comparison (Ops/sec)" + x-axis ["short.md", "medium.md", "long.md", "All files"] + y-axis "Δ from react-markdown (%)" + line [20.933031887463496, -3.684453302257641, -8.930260721316925, -3.80565987816402] %% difference percent +~~~ + +Detailed Tables + +### [sample.md](./lib/fixtures/sample.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 42.98 | 2.51 | 0.0% | coming... | +| `@m2d/react-markdown` | 42.75 | 3.15 | -0.5% | coming... | + +### [short.md](./lib/fixtures/short.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 1851.94 | 2.83 | 0.0% | coming... | +| `@m2d/react-markdown` | 1531.38 | 4.09 | -17.3% | coming... | + +### [medium.md](./lib/fixtures/medium.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 286.57 | 4.25 | 3.8% | coming... | +| `react-markdown` | 276.01 | 4.37 | 0.0% | coming... | + +### [long.md](./lib/fixtures/long.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 20.64 | 4.37 | 9.8% | coming... | +| `react-markdown` | 18.79 | 4.89 | 0.0% | coming... | + +### [short-simple.md](./lib/fixtures/short-simple.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 983.57 | 3.14 | 0.0% | coming... | +| `@m2d/react-markdown` | 975.21 | 3.63 | -0.8% | coming... | + +### [medium-formatting.md](./lib/fixtures/medium-formatting.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 645.43 | 2.25 | 0.0% | coming... | +| `@m2d/react-markdown` | 611.69 | 3.01 | -5.2% | coming... | + +### [long-tutorial.md](./lib/fixtures/long-tutorial.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 390.72 | 2.80 | 8.1% | coming... | +| `react-markdown` | 361.52 | 2.52 | 0.0% | coming... | + +### [gfm-complexity.md](./lib/fixtures/gfm-complexity.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 825.41 | 2.34 | 0.0% | coming... | +| `@m2d/react-markdown` | 771.53 | 3.48 | -6.5% | coming... | + +### [deeply-nested-lists.md](./lib/fixtures/deeply-nested-lists.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 634.68 | 3.02 | 0.0% | coming... | +| `@m2d/react-markdown` | 614.41 | 3.39 | -3.2% | coming... | + +### [site-content.md](./lib/fixtures/site-content.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 649.71 | 2.27 | 0.0% | coming... | +| `@m2d/react-markdown` | 640.20 | 2.69 | -1.5% | coming... | + +### [All files](./lib/fixtures/All files) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 11.36 | 3.68 | 4.0% | coming... | +| `@m2d/react-markdown as nested jsx` | 11.18 | 3.79 | 2.3% | coming... | +| `react-markdown` | 10.93 | 3.83 | 0.0% | coming... | + + + +## Benchmarks with remark-gfm, remark-math, and remark-frontmatter plugins. + +~~~mermaid +xychart-beta + title "Render Speed Comparison (Ops/sec)" + x-axis ["short.md", "medium.md", "long.md", "All files"] + y-axis "Ops/sec (higher is better)" + bar [1074.7174608421187, 178.4132210116435, 15.800009201624405, 8.174038243682] %% react-markdown + bar [983.1686946675665, 184.12467512549756, 16.564404801792207, 7.916570700995681] %% @m2d/react-markdown +~~~ + +~~~mermaid +xychart-beta + title "Render Speed Comparison (Ops/sec)" + x-axis ["short.md", "medium.md", "long.md", "All files"] + y-axis "Δ from react-markdown (%)" + line [9.31160305155029, -3.101949323175291, -4.614687997030218, 3.2522610156685263] %% difference percent +~~~ + +Detailed Tables + +### [sample.md](./lib/fixtures/sample.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 29.08 | 2.16 | 4.4% | coming... | +| `react-markdown` | 27.87 | 1.85 | 0.0% | coming... | + +### [short.md](./lib/fixtures/short.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 1074.72 | 1.35 | 0.0% | coming... | +| `@m2d/react-markdown` | 983.17 | 1.37 | -8.5% | coming... | + +### [medium.md](./lib/fixtures/medium.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 184.12 | 2.91 | 3.2% | coming... | +| `react-markdown` | 178.41 | 2.81 | 0.0% | coming... | + +### [long.md](./lib/fixtures/long.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 16.56 | 3.59 | 4.8% | coming... | +| `react-markdown` | 15.80 | 3.53 | 0.0% | coming... | + +### [short-simple.md](./lib/fixtures/short-simple.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 631.39 | 1.18 | 0.0% | coming... | +| `@m2d/react-markdown` | 598.69 | 1.28 | -5.2% | coming... | + +### [medium-formatting.md](./lib/fixtures/medium-formatting.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 426.92 | 1.14 | 113.4% | coming... | +| `react-markdown` | 200.07 | 7.84 | 0.0% | coming... | + +### [long-tutorial.md](./lib/fixtures/long-tutorial.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 235.69 | 1.57 | 0.0% | coming... | +| `@m2d/react-markdown` | 193.32 | 9.92 | -18.0% | coming... | + +### [gfm-complexity.md](./lib/fixtures/gfm-complexity.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 418.04 | 2.50 | 0.0% | coming... | +| `@m2d/react-markdown` | 414.09 | 3.00 | -0.9% | coming... | + +### [deeply-nested-lists.md](./lib/fixtures/deeply-nested-lists.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 415.30 | 1.70 | 0.8% | coming... | +| `react-markdown` | 411.96 | 1.81 | 0.0% | coming... | + +### [site-content.md](./lib/fixtures/site-content.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 457.94 | 1.41 | 0.0% | coming... | +| `@m2d/react-markdown` | 445.84 | 1.25 | -2.6% | coming... | + +### [All files](./lib/fixtures/All files) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 8.17 | 3.15 | 0.0% | coming... | +| `@m2d/react-markdown as nested jsx` | 8.10 | 2.90 | -0.9% | coming... | +| `@m2d/react-markdown` | 7.92 | 3.33 | -3.1% | coming... | + + + +## Benchmarks with remark-gfm, and rehype-raw plugins. + +~~~mermaid +xychart-beta + title "Render Speed Comparison (Ops/sec)" + x-axis ["short.md", "medium.md", "long.md", "All files"] + y-axis "Ops/sec (higher is better)" + bar [1031.1096191025754, 164.37514683723185, 14.019699516469753, 7.222618931254631] %% react-markdown + bar [870.7057124894626, 162.7275824271953, 14.424855249949237, 7.460295281142587] %% @m2d/react-markdown +~~~ + +~~~mermaid +xychart-beta + title "Render Speed Comparison (Ops/sec)" + x-axis ["short.md", "medium.md", "long.md", "All files"] + y-axis "Δ from react-markdown (%)" + line [18.422287153083772, 1.012467822272033, -2.8087334427907673, -3.1858839487054995] %% difference percent +~~~ + +Detailed Tables + +### [sample.md](./lib/fixtures/sample.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 24.55 | 1.49 | 0.0% | coming... | +| `@m2d/react-markdown` | 24.18 | 1.94 | -1.5% | coming... | + +### [short.md](./lib/fixtures/short.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 1031.11 | 1.14 | 0.0% | coming... | +| `@m2d/react-markdown` | 870.71 | 1.46 | -15.6% | coming... | + +### [medium.md](./lib/fixtures/medium.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 164.38 | 2.44 | 0.0% | coming... | +| `@m2d/react-markdown` | 162.73 | 2.56 | -1.0% | coming... | + +### [long.md](./lib/fixtures/long.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 14.42 | 3.56 | 2.9% | coming... | +| `react-markdown` | 14.02 | 3.40 | 0.0% | coming... | + +### [short-simple.md](./lib/fixtures/short-simple.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 578.70 | 1.43 | 0.0% | coming... | +| `@m2d/react-markdown` | 554.78 | 1.03 | -4.1% | coming... | + +### [medium-formatting.md](./lib/fixtures/medium-formatting.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 422.17 | 1.08 | 0.0% | coming... | +| `@m2d/react-markdown` | 402.98 | 1.07 | -4.5% | coming... | + +### [long-tutorial.md](./lib/fixtures/long-tutorial.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 212.74 | 1.30 | 0.3% | coming... | +| `react-markdown` | 212.08 | 1.18 | 0.0% | coming... | + +### [gfm-complexity.md](./lib/fixtures/gfm-complexity.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 384.92 | 1.79 | 0.0% | coming... | +| `@m2d/react-markdown` | 375.10 | 2.09 | -2.6% | coming... | + +### [deeply-nested-lists.md](./lib/fixtures/deeply-nested-lists.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 392.58 | 1.16 | 0.0% | coming... | +| `@m2d/react-markdown` | 264.71 | 8.59 | -32.6% | coming... | + +### [site-content.md](./lib/fixtures/site-content.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 435.07 | 1.31 | 0.0% | coming... | +| `@m2d/react-markdown` | 411.96 | 1.37 | -5.3% | coming... | + +### [All files](./lib/fixtures/All files) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 7.46 | 2.98 | 3.3% | coming... | +| `react-markdown` | 7.22 | 2.59 | 0.0% | coming... | +| `@m2d/react-markdown as nested jsx` | 5.05 | 12.56 | -30.0% | coming... | + + diff --git a/benchmark-logs/benchmark_2025-07-16T03_03_26.000Z.json b/benchmark-logs/benchmark_2025-07-16T03_03_26.000Z.json new file mode 100644 index 00000000..b6861705 --- /dev/null +++ b/benchmark-logs/benchmark_2025-07-16T03_03_26.000Z.json @@ -0,0 +1,415 @@ +{ + "envInfo": { + "platform": "win32", + "arch": "x64", + "cpu": "11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz", + "cores": 8, + "node": "v20.10.0", + "memory": "15.79 GB", + "Benchmark time": "Wed Jul 16 2025 08:33:26 GMT+0530 (India Standard Time)" + }, + "results": { + "no": { + "sample.md": [ + { + "name": "@m2d/react-markdown", + "ops": 40.783066566324685, + "margin": 2.661043603965218 + }, + { + "name": "react-markdown", + "ops": 39.713028229613265, + "margin": 3.4814662000984695 + } + ], + "short.md": [ + { + "name": "@m2d/react-markdown", + "ops": 1764.4388808432216, + "margin": 3.8686666898134816 + }, + { + "name": "react-markdown", + "ops": 1879.962645100728, + "margin": 3.0019819625151625 + } + ], + "medium.md": [ + { + "name": "@m2d/react-markdown", + "ops": 288.63007354074966, + "margin": 4.2102357217601 + }, + { + "name": "react-markdown", + "ops": 265.37261980873586, + "margin": 4.4334145166274315 + } + ], + "long.md": [ + { + "name": "@m2d/react-markdown", + "ops": 18.23614021035891, + "margin": 5.279913150025072 + }, + { + "name": "react-markdown", + "ops": 15.237887498464271, + "margin": 7.472627479974047 + } + ], + "simple.md": [ + { + "name": "@m2d/react-markdown", + "ops": 1020.0592956469054, + "margin": 4.262995328653272 + }, + { + "name": "react-markdown", + "ops": 1177.7567013493037, + "margin": 3.0874142887099745 + } + ], + "formatting.md": [ + { + "name": "@m2d/react-markdown", + "ops": 733.2498839570549, + "margin": 2.888810006512477 + }, + { + "name": "react-markdown", + "ops": 758.424039014117, + "margin": 2.5908555150666266 + } + ], + "tutorial.md": [ + { + "name": "@m2d/react-markdown", + "ops": 453.09569784380045, + "margin": 2.9619514277433296 + }, + { + "name": "react-markdown", + "ops": 454.19301624869837, + "margin": 2.848865548112153 + } + ], + "gfm-complexity.md": [ + { + "name": "@m2d/react-markdown", + "ops": 936.7250406151065, + "margin": 2.991821906969561 + }, + { + "name": "react-markdown", + "ops": 866.0574034095946, + "margin": 2.7767318102161376 + } + ], + "deeply-nested-lists.md": [ + { + "name": "@m2d/react-markdown", + "ops": 665.0317518751667, + "margin": 4.003602962083501 + }, + { + "name": "react-markdown", + "ops": 724.1123046146485, + "margin": 3.274261049531256 + } + ], + "site-content.md": [ + { + "name": "@m2d/react-markdown", + "ops": 708.6733907578804, + "margin": 3.6054670706243352 + }, + { + "name": "react-markdown", + "ops": 616.5809492411433, + "margin": 2.6199791808637416 + } + ], + "All files": [ + { + "name": "react-markdown", + "ops": 10.19241185378493, + "margin": 3.9462896251545225 + }, + { + "name": "@m2d/react-markdown", + "ops": 10.133560407898365, + "margin": 4.178047843453387 + } + ] + }, + "remark-gfm, remark-math, and remark-frontmatter": { + "sample.md": [ + { + "name": "@m2d/react-markdown", + "ops": 28.73244101557091, + "margin": 2.530171621525724 + }, + { + "name": "react-markdown", + "ops": 29.142933933555984, + "margin": 2.3502878241136593 + } + ], + "short.md": [ + { + "name": "@m2d/react-markdown", + "ops": 951.0962117337364, + "margin": 3.387174851264124 + }, + { + "name": "react-markdown", + "ops": 1089.0568990174372, + "margin": 2.5694864285277297 + } + ], + "medium.md": [ + { + "name": "@m2d/react-markdown", + "ops": 195.387272610289, + "margin": 3.436742371730312 + }, + { + "name": "react-markdown", + "ops": 158.88284646816587, + "margin": 6.184134110620216 + } + ], + "long.md": [ + { + "name": "@m2d/react-markdown", + "ops": 14.860516873811127, + "margin": 4.594454705366346 + }, + { + "name": "react-markdown", + "ops": 14.578606252619634, + "margin": 4.554535315469592 + } + ], + "simple.md": [ + { + "name": "@m2d/react-markdown", + "ops": 603.6594901074635, + "margin": 2.784950337876217 + }, + { + "name": "react-markdown", + "ops": 650.0743277927277, + "margin": 1.9544129604150962 + } + ], + "formatting.md": [ + { + "name": "@m2d/react-markdown", + "ops": 455.19895584073123, + "margin": 2.2178929049841094 + }, + { + "name": "react-markdown", + "ops": 477.49125840194716, + "margin": 1.5338887789107192 + } + ], + "tutorial.md": [ + { + "name": "@m2d/react-markdown", + "ops": 215.75654174032388, + "margin": 3.057963079711194 + }, + { + "name": "react-markdown", + "ops": 225.35154997154035, + "margin": 3.124299858043815 + } + ], + "gfm-complexity.md": [ + { + "name": "@m2d/react-markdown", + "ops": 485.32158072860494, + "margin": 3.1785593399901826 + }, + { + "name": "react-markdown", + "ops": 421.93735395253873, + "margin": 3.0354320111356454 + } + ], + "deeply-nested-lists.md": [ + { + "name": "@m2d/react-markdown", + "ops": 480.0805799394233, + "margin": 2.146717809795406 + }, + { + "name": "react-markdown", + "ops": 447.6945290689255, + "margin": 2.657052357922333 + } + ], + "site-content.md": [ + { + "name": "@m2d/react-markdown", + "ops": 525.698868676371, + "margin": 1.382885939431849 + }, + { + "name": "react-markdown", + "ops": 524.1407411477045, + "margin": 0.8959103982621612 + } + ], + "All files": [ + { + "name": "react-markdown", + "ops": 9.19456457767856, + "margin": 3.3730319175665504 + }, + { + "name": "@m2d/react-markdown", + "ops": 8.96118917853905, + "margin": 3.2974768263001533 + } + ] + }, + "remark-gfm, and rehype-raw": { + "sample.md": [ + { + "name": "@m2d/react-markdown", + "ops": 26.10507804986317, + "margin": 1.8915538869277975 + }, + { + "name": "react-markdown", + "ops": 25.173484977461364, + "margin": 1.7554158473995798 + } + ], + "short.md": [ + { + "name": "@m2d/react-markdown", + "ops": 1073.6895157183899, + "margin": 1.3348575444294135 + }, + { + "name": "react-markdown", + "ops": 1144.86793763487, + "margin": 0.8801264365151708 + } + ], + "medium.md": [ + { + "name": "@m2d/react-markdown", + "ops": 191.00768695360517, + "margin": 2.7601927226664396 + }, + { + "name": "react-markdown", + "ops": 186.6724887049371, + "margin": 2.489867426336936 + } + ], + "long.md": [ + { + "name": "@m2d/react-markdown", + "ops": 16.15020671678501, + "margin": 3.458760489884588 + }, + { + "name": "react-markdown", + "ops": 15.894618270681677, + "margin": 3.854553886008688 + } + ], + "simple.md": [ + { + "name": "@m2d/react-markdown", + "ops": 649.8923806337748, + "margin": 1.0061465255241346 + }, + { + "name": "react-markdown", + "ops": 586.8802132888387, + "margin": 3.816178748390711 + } + ], + "formatting.md": [ + { + "name": "@m2d/react-markdown", + "ops": 235.46064957103835, + "margin": 3.1725279630968535 + }, + { + "name": "react-markdown", + "ops": 236.14592059014348, + "margin": 3.0886616045975956 + } + ], + "tutorial.md": [ + { + "name": "@m2d/react-markdown", + "ops": 116.25241644487154, + "margin": 2.596837611379823 + }, + { + "name": "react-markdown", + "ops": 121.15251191659108, + "margin": 2.977223162138247 + } + ], + "gfm-complexity.md": [ + { + "name": "@m2d/react-markdown", + "ops": 205.57262698376056, + "margin": 3.013421543597351 + }, + { + "name": "react-markdown", + "ops": 209.0951917041034, + "margin": 3.092457401763946 + } + ], + "deeply-nested-lists.md": [ + { + "name": "@m2d/react-markdown", + "ops": 207.25573796737376, + "margin": 2.96911724155366 + }, + { + "name": "react-markdown", + "ops": 199.0681477924004, + "margin": 3.4524793511848486 + } + ], + "site-content.md": [ + { + "name": "@m2d/react-markdown", + "ops": 338.2600767452376, + "margin": 5.689471104194358 + }, + { + "name": "react-markdown", + "ops": 468.8030153114202, + "margin": 2.5870410263457972 + } + ], + "All files": [ + { + "name": "react-markdown", + "ops": 8.02421290194737, + "margin": 3.110394437249887 + }, + { + "name": "@m2d/react-markdown", + "ops": 7.486454817065299, + "margin": 4.002955555461023 + } + ] + } + } +} \ No newline at end of file diff --git a/benchmark-logs/benchmark_2025-07-16T03_03_26.000Z.md b/benchmark-logs/benchmark_2025-07-16T03_03_26.000Z.md new file mode 100644 index 00000000..aeb9fd0f --- /dev/null +++ b/benchmark-logs/benchmark_2025-07-16T03_03_26.000Z.md @@ -0,0 +1,354 @@ +# 📊 Markdown Render Benchmark + +🧠 System Info + +- **platform:** win32 +- **arch:** x64 +- **cpu:** 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz +- **cores:** 8 +- **node:** v20.10.0 +- **memory:** 15.79 GB +- **Benchmark time:** Wed Jul 16 2025 08:33:26 GMT+0530 (India Standard Time) + + +## Benchmarks with no plugins. + +~~~mermaid +xychart-beta + title "Render Speed Comparison (Ops/sec)" + x-axis ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"] + y-axis "Ops/sec (higher is better)" + bar [10.19241185378493, 15.237887498464271, 39.713028229613265, 265.37261980873586, 454.19301624869837, 616.5809492411433, 724.1123046146485, 758.424039014117, 866.0574034095946, 1177.7567013493037, 1879.962645100728] %% react-markdown + bar [10.133560407898365, 18.23614021035891, 40.783066566324685, 288.63007354074966, 453.09569784380045, 708.6733907578804, 665.0317518751667, 733.2498839570549, 936.7250406151065, 1020.0592956469054, 1764.4388808432216] %% @m2d/react-markdown +~~~ + +~~~mermaid +xychart-beta + title "Render Speed Comparison (Ops/sec)" + x-axis ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"] + y-axis "Δ from react-markdown (%)" + line [-0.577404511619213, 19.676301667122917, 2.6944264499918247, 8.764074360337675, -0.2415973750457384, 14.935985555518666, -8.159031736233606, -3.3192717743739144, 8.159694372139704, -13.389641979683189, -6.14500317644964] %% difference percent + line [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] %% Zero line +~~~ + +> **Labels:** +> 1: ***All files***; +> 2: ***long.md***; +> 3: ***sample.md***; +> 4: ***medium.md***; +> 5: ***tutorial.md***; +> 6: ***site-content.md***; +> 7: ***deeply-nested-lists.md***; +> 8: ***formatting.md***; +> 9: ***gfm-complexity.md***; +> 10: ***simple.md***; +> 11: ***short.md***; + +Detailed Tables + +### [sample.md](./lib/fixtures/sample.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 40.78 | 2.66 | 2.7% | coming... | +| `react-markdown` | 39.71 | 3.48 | 0.0% | coming... | + +### [short.md](./lib/fixtures/short.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 1879.96 | 3.00 | 0.0% | coming... | +| `@m2d/react-markdown` | 1764.44 | 3.87 | -6.1% | coming... | + +### [medium.md](./lib/fixtures/medium.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 288.63 | 4.21 | 8.8% | coming... | +| `react-markdown` | 265.37 | 4.43 | 0.0% | coming... | + +### [long.md](./lib/fixtures/long.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 18.24 | 5.28 | 19.7% | coming... | +| `react-markdown` | 15.24 | 7.47 | 0.0% | coming... | + +### [simple.md](./lib/fixtures/simple.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 1177.76 | 3.09 | 0.0% | coming... | +| `@m2d/react-markdown` | 1020.06 | 4.26 | -13.4% | coming... | + +### [formatting.md](./lib/fixtures/formatting.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 758.42 | 2.59 | 0.0% | coming... | +| `@m2d/react-markdown` | 733.25 | 2.89 | -3.3% | coming... | + +### [tutorial.md](./lib/fixtures/tutorial.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 454.19 | 2.85 | 0.0% | coming... | +| `@m2d/react-markdown` | 453.10 | 2.96 | -0.2% | coming... | + +### [gfm-complexity.md](./lib/fixtures/gfm-complexity.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 936.73 | 2.99 | 8.2% | coming... | +| `react-markdown` | 866.06 | 2.78 | 0.0% | coming... | + +### [deeply-nested-lists.md](./lib/fixtures/deeply-nested-lists.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 724.11 | 3.27 | 0.0% | coming... | +| `@m2d/react-markdown` | 665.03 | 4.00 | -8.2% | coming... | + +### [site-content.md](./lib/fixtures/site-content.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 708.67 | 3.61 | 14.9% | coming... | +| `react-markdown` | 616.58 | 2.62 | 0.0% | coming... | + +### [All files](./lib/fixtures/All files) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 10.19 | 3.95 | 0.0% | coming... | +| `@m2d/react-markdown` | 10.13 | 4.18 | -0.6% | coming... | + + + +## Benchmarks with remark-gfm, remark-math, and remark-frontmatter plugins. + +~~~mermaid +xychart-beta + title "Render Speed Comparison (Ops/sec)" + x-axis ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"] + y-axis "Ops/sec (higher is better)" + bar [9.19456457767856, 14.578606252619634, 29.142933933555984, 158.88284646816587, 225.35154997154035, 421.93735395253873, 447.6945290689255, 477.49125840194716, 524.1407411477045, 650.0743277927277, 1089.0568990174372] %% react-markdown + bar [8.96118917853905, 14.860516873811127, 28.73244101557091, 195.387272610289, 215.75654174032388, 485.32158072860494, 480.0805799394233, 455.19895584073123, 525.698868676371, 603.6594901074635, 951.0962117337364] %% @m2d/react-markdown +~~~ + +~~~mermaid +xychart-beta + title "Render Speed Comparison (Ops/sec)" + x-axis ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"] + y-axis "Δ from react-markdown (%)" + line [-2.5381887001595658, 1.9337282062943169, -1.4085504188458573, 22.975687403383244, -4.2577955343232485, 15.022189000880907, 7.233961723376734, -4.6686305076710966, 0.2972727373290489, -7.1399278053114035, -12.667904441739541] %% difference percent + line [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] %% Zero line +~~~ + +> **Labels:** +> 1: ***All files***; +> 2: ***long.md***; +> 3: ***sample.md***; +> 4: ***medium.md***; +> 5: ***tutorial.md***; +> 6: ***gfm-complexity.md***; +> 7: ***deeply-nested-lists.md***; +> 8: ***formatting.md***; +> 9: ***site-content.md***; +> 10: ***simple.md***; +> 11: ***short.md***; + +Detailed Tables + +### [sample.md](./lib/fixtures/sample.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 29.14 | 2.35 | 0.0% | coming... | +| `@m2d/react-markdown` | 28.73 | 2.53 | -1.4% | coming... | + +### [short.md](./lib/fixtures/short.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 1089.06 | 2.57 | 0.0% | coming... | +| `@m2d/react-markdown` | 951.10 | 3.39 | -12.7% | coming... | + +### [medium.md](./lib/fixtures/medium.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 195.39 | 3.44 | 23.0% | coming... | +| `react-markdown` | 158.88 | 6.18 | 0.0% | coming... | + +### [long.md](./lib/fixtures/long.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 14.86 | 4.59 | 1.9% | coming... | +| `react-markdown` | 14.58 | 4.55 | 0.0% | coming... | + +### [simple.md](./lib/fixtures/simple.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 650.07 | 1.95 | 0.0% | coming... | +| `@m2d/react-markdown` | 603.66 | 2.78 | -7.1% | coming... | + +### [formatting.md](./lib/fixtures/formatting.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 477.49 | 1.53 | 0.0% | coming... | +| `@m2d/react-markdown` | 455.20 | 2.22 | -4.7% | coming... | + +### [tutorial.md](./lib/fixtures/tutorial.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 225.35 | 3.12 | 0.0% | coming... | +| `@m2d/react-markdown` | 215.76 | 3.06 | -4.3% | coming... | + +### [gfm-complexity.md](./lib/fixtures/gfm-complexity.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 485.32 | 3.18 | 15.0% | coming... | +| `react-markdown` | 421.94 | 3.04 | 0.0% | coming... | + +### [deeply-nested-lists.md](./lib/fixtures/deeply-nested-lists.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 480.08 | 2.15 | 7.2% | coming... | +| `react-markdown` | 447.69 | 2.66 | 0.0% | coming... | + +### [site-content.md](./lib/fixtures/site-content.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 525.70 | 1.38 | 0.3% | coming... | +| `react-markdown` | 524.14 | 0.90 | 0.0% | coming... | + +### [All files](./lib/fixtures/All files) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 9.19 | 3.37 | 0.0% | coming... | +| `@m2d/react-markdown` | 8.96 | 3.30 | -2.5% | coming... | + + + +## Benchmarks with remark-gfm, and rehype-raw plugins. + +~~~mermaid +xychart-beta + title "Render Speed Comparison (Ops/sec)" + x-axis ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"] + y-axis "Ops/sec (higher is better)" + bar [8.02421290194737, 15.894618270681677, 25.173484977461364, 121.15251191659108, 186.6724887049371, 199.0681477924004, 209.0951917041034, 236.14592059014348, 468.8030153114202, 586.8802132888387, 1144.86793763487] %% react-markdown + bar [7.486454817065299, 16.15020671678501, 26.10507804986317, 116.25241644487154, 191.00768695360517, 207.25573796737376, 205.57262698376056, 235.46064957103835, 338.2600767452376, 649.8923806337748, 1073.6895157183899] %% @m2d/react-markdown +~~~ + +~~~mermaid +xychart-beta + title "Render Speed Comparison (Ops/sec)" + x-axis ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"] + y-axis "Δ from react-markdown (%)" + line [-6.701692632701266, 1.6080187756051836, 3.7006917128712695, -4.0445677883204505, 2.3223552001390373, 4.112958434471321, -1.684670360726288, -0.29018964943057024, -27.846010862251923, 10.736802147719374, -6.217173140818702] %% difference percent + line [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] %% Zero line +~~~ + +> **Labels:** +> 1: ***All files***; +> 2: ***long.md***; +> 3: ***sample.md***; +> 4: ***tutorial.md***; +> 5: ***medium.md***; +> 6: ***deeply-nested-lists.md***; +> 7: ***gfm-complexity.md***; +> 8: ***formatting.md***; +> 9: ***site-content.md***; +> 10: ***simple.md***; +> 11: ***short.md***; + +Detailed Tables + +### [sample.md](./lib/fixtures/sample.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 26.11 | 1.89 | 3.7% | coming... | +| `react-markdown` | 25.17 | 1.76 | 0.0% | coming... | + +### [short.md](./lib/fixtures/short.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 1144.87 | 0.88 | 0.0% | coming... | +| `@m2d/react-markdown` | 1073.69 | 1.33 | -6.2% | coming... | + +### [medium.md](./lib/fixtures/medium.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 191.01 | 2.76 | 2.3% | coming... | +| `react-markdown` | 186.67 | 2.49 | 0.0% | coming... | + +### [long.md](./lib/fixtures/long.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 16.15 | 3.46 | 1.6% | coming... | +| `react-markdown` | 15.89 | 3.85 | 0.0% | coming... | + +### [simple.md](./lib/fixtures/simple.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 649.89 | 1.01 | 10.7% | coming... | +| `react-markdown` | 586.88 | 3.82 | 0.0% | coming... | + +### [formatting.md](./lib/fixtures/formatting.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 236.15 | 3.09 | 0.0% | coming... | +| `@m2d/react-markdown` | 235.46 | 3.17 | -0.3% | coming... | + +### [tutorial.md](./lib/fixtures/tutorial.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 121.15 | 2.98 | 0.0% | coming... | +| `@m2d/react-markdown` | 116.25 | 2.60 | -4.0% | coming... | + +### [gfm-complexity.md](./lib/fixtures/gfm-complexity.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 209.10 | 3.09 | 0.0% | coming... | +| `@m2d/react-markdown` | 205.57 | 3.01 | -1.7% | coming... | + +### [deeply-nested-lists.md](./lib/fixtures/deeply-nested-lists.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `@m2d/react-markdown` | 207.26 | 2.97 | 4.1% | coming... | +| `react-markdown` | 199.07 | 3.45 | 0.0% | coming... | + +### [site-content.md](./lib/fixtures/site-content.md) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 468.80 | 2.59 | 0.0% | coming... | +| `@m2d/react-markdown` | 338.26 | 5.69 | -27.8% | coming... | + +### [All files](./lib/fixtures/All files) + +| Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | +|---|---:|--:|--:|--:| +| `react-markdown` | 8.02 | 3.11 | 0.0% | coming... | +| `@m2d/react-markdown` | 7.49 | 4.00 | -6.7% | coming... | + + diff --git a/benchmark.json b/benchmark.json index 0b779286..b6861705 100644 --- a/benchmark.json +++ b/benchmark.json @@ -1,419 +1,415 @@ { - "no": { - "sample.md": [ - { - "name": "@m2d/react-markdown", - "ops": 42.74708438167588, - "margin": 3.1493983894881623 - }, - { - "name": "react-markdown", - "ops": 42.98277392923757, - "margin": 2.5108926226895676 - } - ], - "short.md": [ - { - "name": "@m2d/react-markdown", - "ops": 1531.3757006079813, - "margin": 4.087216414945013 - }, - { - "name": "react-markdown", - "ops": 1851.9390643331176, - "margin": 2.8258801868390995 - } - ], - "medium.md": [ - { - "name": "@m2d/react-markdown", - "ops": 286.5658635012855, - "margin": 4.248816163584699 - }, - { - "name": "react-markdown", - "ops": 276.00747808036925, - "margin": 4.365476215061842 - } - ], - "long.md": [ - { - "name": "@m2d/react-markdown", - "ops": 20.635262930563872, - "margin": 4.371644878505462 - }, - { - "name": "react-markdown", - "ops": 18.792480150335255, - "margin": 4.886883318740262 - } - ], - "short-simple.md": [ - { - "name": "@m2d/react-markdown", - "ops": 975.2144674133882, - "margin": 3.63220674044318 - }, - { - "name": "react-markdown", - "ops": 983.5741252107894, - "margin": 3.135455816598657 - } - ], - "medium-formatting.md": [ - { - "name": "@m2d/react-markdown", - "ops": 611.6894985569703, - "margin": 3.013959035373157 - }, - { - "name": "react-markdown", - "ops": 645.4271527261262, - "margin": 2.2518994079362176 - } - ], - "long-tutorial.md": [ - { - "name": "@m2d/react-markdown", - "ops": 390.723965985505, - "margin": 2.798733891444964 - }, - { - "name": "react-markdown", - "ops": 361.5177777014237, - "margin": 2.521911127523275 - } - ], - "gfm-complexity.md": [ - { - "name": "@m2d/react-markdown", - "ops": 771.5341523280497, - "margin": 3.479259467012237 - }, - { - "name": "react-markdown", - "ops": 825.411461792101, - "margin": 2.337091485889471 - } - ], - "deeply-nested-lists.md": [ - { - "name": "@m2d/react-markdown", - "ops": 614.4103650712425, - "margin": 3.3878555809063218 - }, - { - "name": "react-markdown", - "ops": 634.6825328027951, - "margin": 3.0217868410897615 - } - ], - "site-content.md": [ - { - "name": "@m2d/react-markdown", - "ops": 640.2005588716024, - "margin": 2.687020064360469 - }, - { - "name": "react-markdown", - "ops": 649.7068546260045, - "margin": 2.2689517784718953 - } - ], - "All files": [ - { - "name": "react-markdown", - "ops": 10.928697086284455, - "margin": 3.8318922533268456 - }, - { - "name": "@m2d/react-markdown", - "ops": 11.361060403806082, - "margin": 3.6759820409301156 - }, - { - "name": "@m2d/react-markdown as nested jsx", - "ops": 11.180671352284898, - "margin": 3.787295962068112 - } - ] + "envInfo": { + "platform": "win32", + "arch": "x64", + "cpu": "11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz", + "cores": 8, + "node": "v20.10.0", + "memory": "15.79 GB", + "Benchmark time": "Wed Jul 16 2025 08:33:26 GMT+0530 (India Standard Time)" }, - "remark-gfm, remark-math, and remark-frontmatter": { - "sample.md": [ - { - "name": "@m2d/react-markdown", - "ops": 29.082675958339877, - "margin": 2.156768616953331 - }, - { - "name": "react-markdown", - "ops": 27.866921662269842, - "margin": 1.854725697011497 - } - ], - "short.md": [ - { - "name": "@m2d/react-markdown", - "ops": 983.1686946675665, - "margin": 1.3743912669953593 - }, - { - "name": "react-markdown", - "ops": 1074.7174608421187, - "margin": 1.3496359984490789 - } - ], - "medium.md": [ - { - "name": "@m2d/react-markdown", - "ops": 184.12467512549756, - "margin": 2.9066671032211078 - }, - { - "name": "react-markdown", - "ops": 178.4132210116435, - "margin": 2.8084319185668463 - } - ], - "long.md": [ - { - "name": "@m2d/react-markdown", - "ops": 16.564404801792207, - "margin": 3.587871940116675 - }, - { - "name": "react-markdown", - "ops": 15.800009201624405, - "margin": 3.5291895862957707 - } - ], - "short-simple.md": [ - { - "name": "@m2d/react-markdown", - "ops": 598.6925479890702, - "margin": 1.2821149562725644 - }, - { - "name": "react-markdown", - "ops": 631.3869509982479, - "margin": 1.1811170152416268 - } - ], - "medium-formatting.md": [ - { - "name": "@m2d/react-markdown", - "ops": 426.9162928299208, - "margin": 1.1355042985631263 - }, - { - "name": "react-markdown", - "ops": 200.0710934220817, - "margin": 7.839700450385986 - } - ], - "long-tutorial.md": [ - { - "name": "@m2d/react-markdown", - "ops": 193.31801041845242, - "margin": 9.921574753902991 - }, - { - "name": "react-markdown", - "ops": 235.68832089226325, - "margin": 1.5726928647003986 - } - ], - "gfm-complexity.md": [ - { - "name": "@m2d/react-markdown", - "ops": 414.0911487677954, - "margin": 2.995465126627123 - }, - { - "name": "react-markdown", - "ops": 418.03644605120616, - "margin": 2.5047022830882675 - } - ], - "deeply-nested-lists.md": [ - { - "name": "@m2d/react-markdown", - "ops": 415.2958547344348, - "margin": 1.7030721973907024 - }, - { - "name": "react-markdown", - "ops": 411.9566502056854, - "margin": 1.8086609089084258 - } - ], - "site-content.md": [ - { - "name": "@m2d/react-markdown", - "ops": 445.8356188710065, - "margin": 1.2457920642045548 - }, - { - "name": "react-markdown", - "ops": 457.94329696482714, - "margin": 1.410380300104795 - } - ], - "All files": [ - { - "name": "react-markdown", - "ops": 8.174038243682, - "margin": 3.1491059579188705 - }, - { - "name": "@m2d/react-markdown", - "ops": 7.916570700995681, - "margin": 3.334001090104863 - }, - { - "name": "@m2d/react-markdown as nested jsx", - "ops": 8.10126172088014, - "margin": 2.896125605566574 - } - ] - }, - "remark-gfm, and rehype-raw": { - "sample.md": [ - { - "name": "@m2d/react-markdown", - "ops": 24.17786223599516, - "margin": 1.9381887247422778 - }, - { - "name": "react-markdown", - "ops": 24.55039890014213, - "margin": 1.485019112819352 - } - ], - "short.md": [ - { - "name": "@m2d/react-markdown", - "ops": 870.7057124894626, - "margin": 1.4584309203699772 - }, - { - "name": "react-markdown", - "ops": 1031.1096191025754, - "margin": 1.1416735228392947 - } - ], - "medium.md": [ - { - "name": "@m2d/react-markdown", - "ops": 162.7275824271953, - "margin": 2.5628139840352153 - }, - { - "name": "react-markdown", - "ops": 164.37514683723185, - "margin": 2.444595974095591 - } - ], - "long.md": [ - { - "name": "@m2d/react-markdown", - "ops": 14.424855249949237, - "margin": 3.5577466182169335 - }, - { - "name": "react-markdown", - "ops": 14.019699516469753, - "margin": 3.403465493485481 - } - ], - "short-simple.md": [ - { - "name": "@m2d/react-markdown", - "ops": 554.7798697813188, - "margin": 1.0263647939516976 - }, - { - "name": "react-markdown", - "ops": 578.7042068259314, - "margin": 1.4260338597432547 - } - ], - "medium-formatting.md": [ - { - "name": "@m2d/react-markdown", - "ops": 402.9810377580538, - "margin": 1.072016811761951 - }, - { - "name": "react-markdown", - "ops": 422.1711023602763, - "margin": 1.084320507025387 - } - ], - "long-tutorial.md": [ - { - "name": "@m2d/react-markdown", - "ops": 212.73842839589844, - "margin": 1.2979512510074058 - }, - { - "name": "react-markdown", - "ops": 212.08201139689257, - "margin": 1.1788314524242725 - } - ], - "gfm-complexity.md": [ - { - "name": "@m2d/react-markdown", - "ops": 375.09715543283266, - "margin": 2.091377602129898 - }, - { - "name": "react-markdown", - "ops": 384.92039307308175, - "margin": 1.7916669054496637 - } - ], - "deeply-nested-lists.md": [ - { - "name": "@m2d/react-markdown", - "ops": 264.7146944640334, - "margin": 8.586728468108886 - }, - { - "name": "react-markdown", - "ops": 392.5829796542143, - "margin": 1.1554806485327342 - } - ], - "site-content.md": [ - { - "name": "@m2d/react-markdown", - "ops": 411.9572994318351, - "margin": 1.3718092923871366 - }, - { - "name": "react-markdown", - "ops": 435.0696872059333, - "margin": 1.3077531830422384 - } - ], - "All files": [ - { - "name": "react-markdown", - "ops": 7.222618931254631, - "margin": 2.5866003742238086 - }, - { - "name": "@m2d/react-markdown", - "ops": 7.460295281142587, - "margin": 2.978680775521445 - }, - { - "name": "@m2d/react-markdown as nested jsx", - "ops": 5.052434356222568, - "margin": 12.555713427904202 - } - ] + "results": { + "no": { + "sample.md": [ + { + "name": "@m2d/react-markdown", + "ops": 40.783066566324685, + "margin": 2.661043603965218 + }, + { + "name": "react-markdown", + "ops": 39.713028229613265, + "margin": 3.4814662000984695 + } + ], + "short.md": [ + { + "name": "@m2d/react-markdown", + "ops": 1764.4388808432216, + "margin": 3.8686666898134816 + }, + { + "name": "react-markdown", + "ops": 1879.962645100728, + "margin": 3.0019819625151625 + } + ], + "medium.md": [ + { + "name": "@m2d/react-markdown", + "ops": 288.63007354074966, + "margin": 4.2102357217601 + }, + { + "name": "react-markdown", + "ops": 265.37261980873586, + "margin": 4.4334145166274315 + } + ], + "long.md": [ + { + "name": "@m2d/react-markdown", + "ops": 18.23614021035891, + "margin": 5.279913150025072 + }, + { + "name": "react-markdown", + "ops": 15.237887498464271, + "margin": 7.472627479974047 + } + ], + "simple.md": [ + { + "name": "@m2d/react-markdown", + "ops": 1020.0592956469054, + "margin": 4.262995328653272 + }, + { + "name": "react-markdown", + "ops": 1177.7567013493037, + "margin": 3.0874142887099745 + } + ], + "formatting.md": [ + { + "name": "@m2d/react-markdown", + "ops": 733.2498839570549, + "margin": 2.888810006512477 + }, + { + "name": "react-markdown", + "ops": 758.424039014117, + "margin": 2.5908555150666266 + } + ], + "tutorial.md": [ + { + "name": "@m2d/react-markdown", + "ops": 453.09569784380045, + "margin": 2.9619514277433296 + }, + { + "name": "react-markdown", + "ops": 454.19301624869837, + "margin": 2.848865548112153 + } + ], + "gfm-complexity.md": [ + { + "name": "@m2d/react-markdown", + "ops": 936.7250406151065, + "margin": 2.991821906969561 + }, + { + "name": "react-markdown", + "ops": 866.0574034095946, + "margin": 2.7767318102161376 + } + ], + "deeply-nested-lists.md": [ + { + "name": "@m2d/react-markdown", + "ops": 665.0317518751667, + "margin": 4.003602962083501 + }, + { + "name": "react-markdown", + "ops": 724.1123046146485, + "margin": 3.274261049531256 + } + ], + "site-content.md": [ + { + "name": "@m2d/react-markdown", + "ops": 708.6733907578804, + "margin": 3.6054670706243352 + }, + { + "name": "react-markdown", + "ops": 616.5809492411433, + "margin": 2.6199791808637416 + } + ], + "All files": [ + { + "name": "react-markdown", + "ops": 10.19241185378493, + "margin": 3.9462896251545225 + }, + { + "name": "@m2d/react-markdown", + "ops": 10.133560407898365, + "margin": 4.178047843453387 + } + ] + }, + "remark-gfm, remark-math, and remark-frontmatter": { + "sample.md": [ + { + "name": "@m2d/react-markdown", + "ops": 28.73244101557091, + "margin": 2.530171621525724 + }, + { + "name": "react-markdown", + "ops": 29.142933933555984, + "margin": 2.3502878241136593 + } + ], + "short.md": [ + { + "name": "@m2d/react-markdown", + "ops": 951.0962117337364, + "margin": 3.387174851264124 + }, + { + "name": "react-markdown", + "ops": 1089.0568990174372, + "margin": 2.5694864285277297 + } + ], + "medium.md": [ + { + "name": "@m2d/react-markdown", + "ops": 195.387272610289, + "margin": 3.436742371730312 + }, + { + "name": "react-markdown", + "ops": 158.88284646816587, + "margin": 6.184134110620216 + } + ], + "long.md": [ + { + "name": "@m2d/react-markdown", + "ops": 14.860516873811127, + "margin": 4.594454705366346 + }, + { + "name": "react-markdown", + "ops": 14.578606252619634, + "margin": 4.554535315469592 + } + ], + "simple.md": [ + { + "name": "@m2d/react-markdown", + "ops": 603.6594901074635, + "margin": 2.784950337876217 + }, + { + "name": "react-markdown", + "ops": 650.0743277927277, + "margin": 1.9544129604150962 + } + ], + "formatting.md": [ + { + "name": "@m2d/react-markdown", + "ops": 455.19895584073123, + "margin": 2.2178929049841094 + }, + { + "name": "react-markdown", + "ops": 477.49125840194716, + "margin": 1.5338887789107192 + } + ], + "tutorial.md": [ + { + "name": "@m2d/react-markdown", + "ops": 215.75654174032388, + "margin": 3.057963079711194 + }, + { + "name": "react-markdown", + "ops": 225.35154997154035, + "margin": 3.124299858043815 + } + ], + "gfm-complexity.md": [ + { + "name": "@m2d/react-markdown", + "ops": 485.32158072860494, + "margin": 3.1785593399901826 + }, + { + "name": "react-markdown", + "ops": 421.93735395253873, + "margin": 3.0354320111356454 + } + ], + "deeply-nested-lists.md": [ + { + "name": "@m2d/react-markdown", + "ops": 480.0805799394233, + "margin": 2.146717809795406 + }, + { + "name": "react-markdown", + "ops": 447.6945290689255, + "margin": 2.657052357922333 + } + ], + "site-content.md": [ + { + "name": "@m2d/react-markdown", + "ops": 525.698868676371, + "margin": 1.382885939431849 + }, + { + "name": "react-markdown", + "ops": 524.1407411477045, + "margin": 0.8959103982621612 + } + ], + "All files": [ + { + "name": "react-markdown", + "ops": 9.19456457767856, + "margin": 3.3730319175665504 + }, + { + "name": "@m2d/react-markdown", + "ops": 8.96118917853905, + "margin": 3.2974768263001533 + } + ] + }, + "remark-gfm, and rehype-raw": { + "sample.md": [ + { + "name": "@m2d/react-markdown", + "ops": 26.10507804986317, + "margin": 1.8915538869277975 + }, + { + "name": "react-markdown", + "ops": 25.173484977461364, + "margin": 1.7554158473995798 + } + ], + "short.md": [ + { + "name": "@m2d/react-markdown", + "ops": 1073.6895157183899, + "margin": 1.3348575444294135 + }, + { + "name": "react-markdown", + "ops": 1144.86793763487, + "margin": 0.8801264365151708 + } + ], + "medium.md": [ + { + "name": "@m2d/react-markdown", + "ops": 191.00768695360517, + "margin": 2.7601927226664396 + }, + { + "name": "react-markdown", + "ops": 186.6724887049371, + "margin": 2.489867426336936 + } + ], + "long.md": [ + { + "name": "@m2d/react-markdown", + "ops": 16.15020671678501, + "margin": 3.458760489884588 + }, + { + "name": "react-markdown", + "ops": 15.894618270681677, + "margin": 3.854553886008688 + } + ], + "simple.md": [ + { + "name": "@m2d/react-markdown", + "ops": 649.8923806337748, + "margin": 1.0061465255241346 + }, + { + "name": "react-markdown", + "ops": 586.8802132888387, + "margin": 3.816178748390711 + } + ], + "formatting.md": [ + { + "name": "@m2d/react-markdown", + "ops": 235.46064957103835, + "margin": 3.1725279630968535 + }, + { + "name": "react-markdown", + "ops": 236.14592059014348, + "margin": 3.0886616045975956 + } + ], + "tutorial.md": [ + { + "name": "@m2d/react-markdown", + "ops": 116.25241644487154, + "margin": 2.596837611379823 + }, + { + "name": "react-markdown", + "ops": 121.15251191659108, + "margin": 2.977223162138247 + } + ], + "gfm-complexity.md": [ + { + "name": "@m2d/react-markdown", + "ops": 205.57262698376056, + "margin": 3.013421543597351 + }, + { + "name": "react-markdown", + "ops": 209.0951917041034, + "margin": 3.092457401763946 + } + ], + "deeply-nested-lists.md": [ + { + "name": "@m2d/react-markdown", + "ops": 207.25573796737376, + "margin": 2.96911724155366 + }, + { + "name": "react-markdown", + "ops": 199.0681477924004, + "margin": 3.4524793511848486 + } + ], + "site-content.md": [ + { + "name": "@m2d/react-markdown", + "ops": 338.2600767452376, + "margin": 5.689471104194358 + }, + { + "name": "react-markdown", + "ops": 468.8030153114202, + "margin": 2.5870410263457972 + } + ], + "All files": [ + { + "name": "react-markdown", + "ops": 8.02421290194737, + "margin": 3.110394437249887 + }, + { + "name": "@m2d/react-markdown", + "ops": 7.486454817065299, + "margin": 4.002955555461023 + } + ] + } } } \ No newline at end of file diff --git a/benchmark.md b/benchmark.md index c105a02f..aeb9fd0f 100644 --- a/benchmark.md +++ b/benchmark.md @@ -8,7 +8,7 @@ - **cores:** 8 - **node:** v20.10.0 - **memory:** 15.79 GB -- **Benchmark time:** Sat Jul 12 2025 01:17:07 GMT+0530 (India Standard Time) +- **Benchmark time:** Wed Jul 16 2025 08:33:26 GMT+0530 (India Standard Time) ## Benchmarks with no plugins. @@ -16,99 +16,112 @@ ~~~mermaid xychart-beta title "Render Speed Comparison (Ops/sec)" - x-axis ["short.md", "medium.md", "long.md", "All files"] + x-axis ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"] y-axis "Ops/sec (higher is better)" - bar [1851.9390643331176, 276.00747808036925, 18.792480150335255, 10.928697086284455] %% react-markdown - bar [1531.3757006079813, 286.5658635012855, 20.635262930563872, 11.361060403806082] %% @m2d/react-markdown + bar [10.19241185378493, 15.237887498464271, 39.713028229613265, 265.37261980873586, 454.19301624869837, 616.5809492411433, 724.1123046146485, 758.424039014117, 866.0574034095946, 1177.7567013493037, 1879.962645100728] %% react-markdown + bar [10.133560407898365, 18.23614021035891, 40.783066566324685, 288.63007354074966, 453.09569784380045, 708.6733907578804, 665.0317518751667, 733.2498839570549, 936.7250406151065, 1020.0592956469054, 1764.4388808432216] %% @m2d/react-markdown ~~~ ~~~mermaid xychart-beta title "Render Speed Comparison (Ops/sec)" - x-axis ["short.md", "medium.md", "long.md", "All files"] + x-axis ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"] y-axis "Δ from react-markdown (%)" - line [20.933031887463496, -3.684453302257641, -8.930260721316925, -3.80565987816402] %% difference percent + line [-0.577404511619213, 19.676301667122917, 2.6944264499918247, 8.764074360337675, -0.2415973750457384, 14.935985555518666, -8.159031736233606, -3.3192717743739144, 8.159694372139704, -13.389641979683189, -6.14500317644964] %% difference percent + line [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] %% Zero line ~~~ +> **Labels:** +> 1: ***All files***; +> 2: ***long.md***; +> 3: ***sample.md***; +> 4: ***medium.md***; +> 5: ***tutorial.md***; +> 6: ***site-content.md***; +> 7: ***deeply-nested-lists.md***; +> 8: ***formatting.md***; +> 9: ***gfm-complexity.md***; +> 10: ***simple.md***; +> 11: ***short.md***; + Detailed Tables ### [sample.md](./lib/fixtures/sample.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 42.98 | 2.51 | 0.0% | coming... | -| `@m2d/react-markdown` | 42.75 | 3.15 | -0.5% | coming... | +| `@m2d/react-markdown` | 40.78 | 2.66 | 2.7% | coming... | +| `react-markdown` | 39.71 | 3.48 | 0.0% | coming... | ### [short.md](./lib/fixtures/short.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 1851.94 | 2.83 | 0.0% | coming... | -| `@m2d/react-markdown` | 1531.38 | 4.09 | -17.3% | coming... | +| `react-markdown` | 1879.96 | 3.00 | 0.0% | coming... | +| `@m2d/react-markdown` | 1764.44 | 3.87 | -6.1% | coming... | ### [medium.md](./lib/fixtures/medium.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `@m2d/react-markdown` | 286.57 | 4.25 | 3.8% | coming... | -| `react-markdown` | 276.01 | 4.37 | 0.0% | coming... | +| `@m2d/react-markdown` | 288.63 | 4.21 | 8.8% | coming... | +| `react-markdown` | 265.37 | 4.43 | 0.0% | coming... | ### [long.md](./lib/fixtures/long.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `@m2d/react-markdown` | 20.64 | 4.37 | 9.8% | coming... | -| `react-markdown` | 18.79 | 4.89 | 0.0% | coming... | +| `@m2d/react-markdown` | 18.24 | 5.28 | 19.7% | coming... | +| `react-markdown` | 15.24 | 7.47 | 0.0% | coming... | -### [short-simple.md](./lib/fixtures/short-simple.md) +### [simple.md](./lib/fixtures/simple.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 983.57 | 3.14 | 0.0% | coming... | -| `@m2d/react-markdown` | 975.21 | 3.63 | -0.8% | coming... | +| `react-markdown` | 1177.76 | 3.09 | 0.0% | coming... | +| `@m2d/react-markdown` | 1020.06 | 4.26 | -13.4% | coming... | -### [medium-formatting.md](./lib/fixtures/medium-formatting.md) +### [formatting.md](./lib/fixtures/formatting.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 645.43 | 2.25 | 0.0% | coming... | -| `@m2d/react-markdown` | 611.69 | 3.01 | -5.2% | coming... | +| `react-markdown` | 758.42 | 2.59 | 0.0% | coming... | +| `@m2d/react-markdown` | 733.25 | 2.89 | -3.3% | coming... | -### [long-tutorial.md](./lib/fixtures/long-tutorial.md) +### [tutorial.md](./lib/fixtures/tutorial.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `@m2d/react-markdown` | 390.72 | 2.80 | 8.1% | coming... | -| `react-markdown` | 361.52 | 2.52 | 0.0% | coming... | +| `react-markdown` | 454.19 | 2.85 | 0.0% | coming... | +| `@m2d/react-markdown` | 453.10 | 2.96 | -0.2% | coming... | ### [gfm-complexity.md](./lib/fixtures/gfm-complexity.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 825.41 | 2.34 | 0.0% | coming... | -| `@m2d/react-markdown` | 771.53 | 3.48 | -6.5% | coming... | +| `@m2d/react-markdown` | 936.73 | 2.99 | 8.2% | coming... | +| `react-markdown` | 866.06 | 2.78 | 0.0% | coming... | ### [deeply-nested-lists.md](./lib/fixtures/deeply-nested-lists.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 634.68 | 3.02 | 0.0% | coming... | -| `@m2d/react-markdown` | 614.41 | 3.39 | -3.2% | coming... | +| `react-markdown` | 724.11 | 3.27 | 0.0% | coming... | +| `@m2d/react-markdown` | 665.03 | 4.00 | -8.2% | coming... | ### [site-content.md](./lib/fixtures/site-content.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 649.71 | 2.27 | 0.0% | coming... | -| `@m2d/react-markdown` | 640.20 | 2.69 | -1.5% | coming... | +| `@m2d/react-markdown` | 708.67 | 3.61 | 14.9% | coming... | +| `react-markdown` | 616.58 | 2.62 | 0.0% | coming... | ### [All files](./lib/fixtures/All files) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `@m2d/react-markdown` | 11.36 | 3.68 | 4.0% | coming... | -| `@m2d/react-markdown as nested jsx` | 11.18 | 3.79 | 2.3% | coming... | -| `react-markdown` | 10.93 | 3.83 | 0.0% | coming... | +| `react-markdown` | 10.19 | 3.95 | 0.0% | coming... | +| `@m2d/react-markdown` | 10.13 | 4.18 | -0.6% | coming... | @@ -117,99 +130,112 @@ xychart-beta ~~~mermaid xychart-beta title "Render Speed Comparison (Ops/sec)" - x-axis ["short.md", "medium.md", "long.md", "All files"] + x-axis ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"] y-axis "Ops/sec (higher is better)" - bar [1074.7174608421187, 178.4132210116435, 15.800009201624405, 8.174038243682] %% react-markdown - bar [983.1686946675665, 184.12467512549756, 16.564404801792207, 7.916570700995681] %% @m2d/react-markdown + bar [9.19456457767856, 14.578606252619634, 29.142933933555984, 158.88284646816587, 225.35154997154035, 421.93735395253873, 447.6945290689255, 477.49125840194716, 524.1407411477045, 650.0743277927277, 1089.0568990174372] %% react-markdown + bar [8.96118917853905, 14.860516873811127, 28.73244101557091, 195.387272610289, 215.75654174032388, 485.32158072860494, 480.0805799394233, 455.19895584073123, 525.698868676371, 603.6594901074635, 951.0962117337364] %% @m2d/react-markdown ~~~ ~~~mermaid xychart-beta title "Render Speed Comparison (Ops/sec)" - x-axis ["short.md", "medium.md", "long.md", "All files"] + x-axis ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"] y-axis "Δ from react-markdown (%)" - line [9.31160305155029, -3.101949323175291, -4.614687997030218, 3.2522610156685263] %% difference percent + line [-2.5381887001595658, 1.9337282062943169, -1.4085504188458573, 22.975687403383244, -4.2577955343232485, 15.022189000880907, 7.233961723376734, -4.6686305076710966, 0.2972727373290489, -7.1399278053114035, -12.667904441739541] %% difference percent + line [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] %% Zero line ~~~ +> **Labels:** +> 1: ***All files***; +> 2: ***long.md***; +> 3: ***sample.md***; +> 4: ***medium.md***; +> 5: ***tutorial.md***; +> 6: ***gfm-complexity.md***; +> 7: ***deeply-nested-lists.md***; +> 8: ***formatting.md***; +> 9: ***site-content.md***; +> 10: ***simple.md***; +> 11: ***short.md***; + Detailed Tables ### [sample.md](./lib/fixtures/sample.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `@m2d/react-markdown` | 29.08 | 2.16 | 4.4% | coming... | -| `react-markdown` | 27.87 | 1.85 | 0.0% | coming... | +| `react-markdown` | 29.14 | 2.35 | 0.0% | coming... | +| `@m2d/react-markdown` | 28.73 | 2.53 | -1.4% | coming... | ### [short.md](./lib/fixtures/short.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 1074.72 | 1.35 | 0.0% | coming... | -| `@m2d/react-markdown` | 983.17 | 1.37 | -8.5% | coming... | +| `react-markdown` | 1089.06 | 2.57 | 0.0% | coming... | +| `@m2d/react-markdown` | 951.10 | 3.39 | -12.7% | coming... | ### [medium.md](./lib/fixtures/medium.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `@m2d/react-markdown` | 184.12 | 2.91 | 3.2% | coming... | -| `react-markdown` | 178.41 | 2.81 | 0.0% | coming... | +| `@m2d/react-markdown` | 195.39 | 3.44 | 23.0% | coming... | +| `react-markdown` | 158.88 | 6.18 | 0.0% | coming... | ### [long.md](./lib/fixtures/long.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `@m2d/react-markdown` | 16.56 | 3.59 | 4.8% | coming... | -| `react-markdown` | 15.80 | 3.53 | 0.0% | coming... | +| `@m2d/react-markdown` | 14.86 | 4.59 | 1.9% | coming... | +| `react-markdown` | 14.58 | 4.55 | 0.0% | coming... | -### [short-simple.md](./lib/fixtures/short-simple.md) +### [simple.md](./lib/fixtures/simple.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 631.39 | 1.18 | 0.0% | coming... | -| `@m2d/react-markdown` | 598.69 | 1.28 | -5.2% | coming... | +| `react-markdown` | 650.07 | 1.95 | 0.0% | coming... | +| `@m2d/react-markdown` | 603.66 | 2.78 | -7.1% | coming... | -### [medium-formatting.md](./lib/fixtures/medium-formatting.md) +### [formatting.md](./lib/fixtures/formatting.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `@m2d/react-markdown` | 426.92 | 1.14 | 113.4% | coming... | -| `react-markdown` | 200.07 | 7.84 | 0.0% | coming... | +| `react-markdown` | 477.49 | 1.53 | 0.0% | coming... | +| `@m2d/react-markdown` | 455.20 | 2.22 | -4.7% | coming... | -### [long-tutorial.md](./lib/fixtures/long-tutorial.md) +### [tutorial.md](./lib/fixtures/tutorial.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 235.69 | 1.57 | 0.0% | coming... | -| `@m2d/react-markdown` | 193.32 | 9.92 | -18.0% | coming... | +| `react-markdown` | 225.35 | 3.12 | 0.0% | coming... | +| `@m2d/react-markdown` | 215.76 | 3.06 | -4.3% | coming... | ### [gfm-complexity.md](./lib/fixtures/gfm-complexity.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 418.04 | 2.50 | 0.0% | coming... | -| `@m2d/react-markdown` | 414.09 | 3.00 | -0.9% | coming... | +| `@m2d/react-markdown` | 485.32 | 3.18 | 15.0% | coming... | +| `react-markdown` | 421.94 | 3.04 | 0.0% | coming... | ### [deeply-nested-lists.md](./lib/fixtures/deeply-nested-lists.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `@m2d/react-markdown` | 415.30 | 1.70 | 0.8% | coming... | -| `react-markdown` | 411.96 | 1.81 | 0.0% | coming... | +| `@m2d/react-markdown` | 480.08 | 2.15 | 7.2% | coming... | +| `react-markdown` | 447.69 | 2.66 | 0.0% | coming... | ### [site-content.md](./lib/fixtures/site-content.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 457.94 | 1.41 | 0.0% | coming... | -| `@m2d/react-markdown` | 445.84 | 1.25 | -2.6% | coming... | +| `@m2d/react-markdown` | 525.70 | 1.38 | 0.3% | coming... | +| `react-markdown` | 524.14 | 0.90 | 0.0% | coming... | ### [All files](./lib/fixtures/All files) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 8.17 | 3.15 | 0.0% | coming... | -| `@m2d/react-markdown as nested jsx` | 8.10 | 2.90 | -0.9% | coming... | -| `@m2d/react-markdown` | 7.92 | 3.33 | -3.1% | coming... | +| `react-markdown` | 9.19 | 3.37 | 0.0% | coming... | +| `@m2d/react-markdown` | 8.96 | 3.30 | -2.5% | coming... | @@ -218,98 +244,111 @@ xychart-beta ~~~mermaid xychart-beta title "Render Speed Comparison (Ops/sec)" - x-axis ["short.md", "medium.md", "long.md", "All files"] + x-axis ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"] y-axis "Ops/sec (higher is better)" - bar [1031.1096191025754, 164.37514683723185, 14.019699516469753, 7.222618931254631] %% react-markdown - bar [870.7057124894626, 162.7275824271953, 14.424855249949237, 7.460295281142587] %% @m2d/react-markdown + bar [8.02421290194737, 15.894618270681677, 25.173484977461364, 121.15251191659108, 186.6724887049371, 199.0681477924004, 209.0951917041034, 236.14592059014348, 468.8030153114202, 586.8802132888387, 1144.86793763487] %% react-markdown + bar [7.486454817065299, 16.15020671678501, 26.10507804986317, 116.25241644487154, 191.00768695360517, 207.25573796737376, 205.57262698376056, 235.46064957103835, 338.2600767452376, 649.8923806337748, 1073.6895157183899] %% @m2d/react-markdown ~~~ ~~~mermaid xychart-beta title "Render Speed Comparison (Ops/sec)" - x-axis ["short.md", "medium.md", "long.md", "All files"] + x-axis ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"] y-axis "Δ from react-markdown (%)" - line [18.422287153083772, 1.012467822272033, -2.8087334427907673, -3.1858839487054995] %% difference percent + line [-6.701692632701266, 1.6080187756051836, 3.7006917128712695, -4.0445677883204505, 2.3223552001390373, 4.112958434471321, -1.684670360726288, -0.29018964943057024, -27.846010862251923, 10.736802147719374, -6.217173140818702] %% difference percent + line [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] %% Zero line ~~~ +> **Labels:** +> 1: ***All files***; +> 2: ***long.md***; +> 3: ***sample.md***; +> 4: ***tutorial.md***; +> 5: ***medium.md***; +> 6: ***deeply-nested-lists.md***; +> 7: ***gfm-complexity.md***; +> 8: ***formatting.md***; +> 9: ***site-content.md***; +> 10: ***simple.md***; +> 11: ***short.md***; + Detailed Tables ### [sample.md](./lib/fixtures/sample.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 24.55 | 1.49 | 0.0% | coming... | -| `@m2d/react-markdown` | 24.18 | 1.94 | -1.5% | coming... | +| `@m2d/react-markdown` | 26.11 | 1.89 | 3.7% | coming... | +| `react-markdown` | 25.17 | 1.76 | 0.0% | coming... | ### [short.md](./lib/fixtures/short.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 1031.11 | 1.14 | 0.0% | coming... | -| `@m2d/react-markdown` | 870.71 | 1.46 | -15.6% | coming... | +| `react-markdown` | 1144.87 | 0.88 | 0.0% | coming... | +| `@m2d/react-markdown` | 1073.69 | 1.33 | -6.2% | coming... | ### [medium.md](./lib/fixtures/medium.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 164.38 | 2.44 | 0.0% | coming... | -| `@m2d/react-markdown` | 162.73 | 2.56 | -1.0% | coming... | +| `@m2d/react-markdown` | 191.01 | 2.76 | 2.3% | coming... | +| `react-markdown` | 186.67 | 2.49 | 0.0% | coming... | ### [long.md](./lib/fixtures/long.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `@m2d/react-markdown` | 14.42 | 3.56 | 2.9% | coming... | -| `react-markdown` | 14.02 | 3.40 | 0.0% | coming... | +| `@m2d/react-markdown` | 16.15 | 3.46 | 1.6% | coming... | +| `react-markdown` | 15.89 | 3.85 | 0.0% | coming... | -### [short-simple.md](./lib/fixtures/short-simple.md) +### [simple.md](./lib/fixtures/simple.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 578.70 | 1.43 | 0.0% | coming... | -| `@m2d/react-markdown` | 554.78 | 1.03 | -4.1% | coming... | +| `@m2d/react-markdown` | 649.89 | 1.01 | 10.7% | coming... | +| `react-markdown` | 586.88 | 3.82 | 0.0% | coming... | -### [medium-formatting.md](./lib/fixtures/medium-formatting.md) +### [formatting.md](./lib/fixtures/formatting.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 422.17 | 1.08 | 0.0% | coming... | -| `@m2d/react-markdown` | 402.98 | 1.07 | -4.5% | coming... | +| `react-markdown` | 236.15 | 3.09 | 0.0% | coming... | +| `@m2d/react-markdown` | 235.46 | 3.17 | -0.3% | coming... | -### [long-tutorial.md](./lib/fixtures/long-tutorial.md) +### [tutorial.md](./lib/fixtures/tutorial.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `@m2d/react-markdown` | 212.74 | 1.30 | 0.3% | coming... | -| `react-markdown` | 212.08 | 1.18 | 0.0% | coming... | +| `react-markdown` | 121.15 | 2.98 | 0.0% | coming... | +| `@m2d/react-markdown` | 116.25 | 2.60 | -4.0% | coming... | ### [gfm-complexity.md](./lib/fixtures/gfm-complexity.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 384.92 | 1.79 | 0.0% | coming... | -| `@m2d/react-markdown` | 375.10 | 2.09 | -2.6% | coming... | +| `react-markdown` | 209.10 | 3.09 | 0.0% | coming... | +| `@m2d/react-markdown` | 205.57 | 3.01 | -1.7% | coming... | ### [deeply-nested-lists.md](./lib/fixtures/deeply-nested-lists.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 392.58 | 1.16 | 0.0% | coming... | -| `@m2d/react-markdown` | 264.71 | 8.59 | -32.6% | coming... | +| `@m2d/react-markdown` | 207.26 | 2.97 | 4.1% | coming... | +| `react-markdown` | 199.07 | 3.45 | 0.0% | coming... | ### [site-content.md](./lib/fixtures/site-content.md) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `react-markdown` | 435.07 | 1.31 | 0.0% | coming... | -| `@m2d/react-markdown` | 411.96 | 1.37 | -5.3% | coming... | +| `react-markdown` | 468.80 | 2.59 | 0.0% | coming... | +| `@m2d/react-markdown` | 338.26 | 5.69 | -27.8% | coming... | ### [All files](./lib/fixtures/All files) | Library | Ops/sec | ±% | Δ from baseline | Memory (KB) | |---|---:|--:|--:|--:| -| `@m2d/react-markdown` | 7.46 | 2.98 | 3.3% | coming... | -| `react-markdown` | 7.22 | 2.59 | 0.0% | coming... | -| `@m2d/react-markdown as nested jsx` | 5.05 | 12.56 | -30.0% | coming... | +| `react-markdown` | 8.02 | 3.11 | 0.0% | coming... | +| `@m2d/react-markdown` | 7.49 | 4.00 | -6.7% | coming... | diff --git a/lib/CHANGELOG.md b/lib/CHANGELOG.md index 126245ff..307a5293 100644 --- a/lib/CHANGELOG.md +++ b/lib/CHANGELOG.md @@ -1,5 +1,11 @@ # @m2d/react-markdown +## 1.0.0 + +### Major Changes + +- 344c4d2: Default Md now accepts only string children. For Mdx we are exposing another component from server/mdx. + ## 0.3.0 ### Minor Changes diff --git a/lib/benchmarks/perf.bench.tsx b/lib/benchmarks/perf.bench.tsx index 30ef3b77..5bb008e8 100644 --- a/lib/benchmarks/perf.bench.tsx +++ b/lib/benchmarks/perf.bench.tsx @@ -11,6 +11,18 @@ import rehypeRaw from "rehype-raw"; import { files, markdowns } from "../fixtures"; import { writeBenchmarkMarkdown } from "./writer"; import { PluggableList } from "unified"; +import os from "os"; +import process from "process"; + +const envInfo = { + platform: os.platform(), // 'win32', 'linux', 'darwin' + arch: os.arch(), // 'x64' + cpu: os.cpus()[0].model, + cores: os.cpus().length, + node: process.version, + memory: `${(os.totalmem() / 1024 ** 3).toFixed(2)} GB`, + "Benchmark time": new Date().toString(), +}; const log = console.log; @@ -119,19 +131,6 @@ Object.entries(pluginLists).forEach(([pluginDescription, plugins]) => { }, { minSamples: 100 }, ) - .add( - "@m2d/react-markdown as nested jsx", - () => { - render( - - {markdowns.map((markdown, i) => ( - {markdown} - ))} - , - ); - }, - { minSamples: 100 }, - ) .on("cycle", (event: any) => { log(String(event.target)); }) @@ -159,6 +158,6 @@ Object.entries(pluginLists).forEach(([pluginDescription, plugins]) => { .run({ async: false }); }); -writeBenchmarkMarkdown(benchmarkResults); +writeBenchmarkMarkdown({ results: benchmarkResults, envInfo }); log(chalk.green(`\n✅ Written to benchmark.md`)); diff --git a/lib/benchmarks/writer.ts b/lib/benchmarks/writer.ts index 8b1723ef..2260ee25 100644 --- a/lib/benchmarks/writer.ts +++ b/lib/benchmarks/writer.ts @@ -2,26 +2,41 @@ import fs from "fs"; import path from "path"; import { BenchResults } from "./perf.bench"; import benchMarkResults from "../../benchmark.json"; -import os from "os"; -import process from "process"; - -const envInfo = { - platform: os.platform(), // 'win32', 'linux', 'darwin' - arch: os.arch(), // 'x64' - cpu: os.cpus()[0].model, - cores: os.cpus().length, - node: process.version, - memory: `${(os.totalmem() / 1024 ** 3).toFixed(2)} GB`, - "Benchmark time": new Date().toString(), -}; + +interface Results { + results: BenchResults; + envInfo: { + platform: string; + arch: string; + cpu: string; + cores: number; + node: string; + memory: string; + "Benchmark time": string; + }; +} export function writeBenchmarkMarkdown( - results: BenchResults = benchMarkResults, + benchResults: Results = benchMarkResults, outPath = "benchmark.md", ) { + const { results, envInfo } = benchResults; fs.writeFileSync( path.resolve("..", outPath.slice(0, -2) + "json"), - JSON.stringify(results, null, 2), + JSON.stringify(benchResults, null, 2), + ); + + const logsDir = path.resolve("..", "benchmark-logs"); + const logsOutPath = + outPath.slice(0, -3) + + "_" + + new Date(envInfo["Benchmark time"]).toISOString().replace(/:/g, "_"); + + if (!fs.existsSync(logsDir)) fs.mkdirSync(logsDir); + + fs.writeFileSync( + path.resolve(logsDir, logsOutPath + ".json"), + JSON.stringify(benchResults, null, 2), ); const md: string[] = []; @@ -38,22 +53,26 @@ export function writeBenchmarkMarkdown( Object.entries(results).forEach(([pluginDescription, fileResults]) => { md.push(`\n## Benchmarks with ${pluginDescription} plugins.\n`); - const chart1Files = ["short.md", "medium.md", "long.md", "All files"]; + const chart1Files = Object.keys(fileResults).sort( + (f1, f2) => + fileResults[f1].reduce((acc, curr) => acc + curr.ops, 0) - + fileResults[f2].reduce((acc, curr) => acc + curr.ops, 0), + ); const res1: number[] = []; const res2: number[] = []; const res3: number[] = []; chart1Files.forEach(testName => { - const r1 = fileResults[testName].find(row => row.name === "react-markdown")?.ops ?? 0; + const baseline = fileResults[testName].find(row => row.name === "react-markdown")?.ops ?? 0; const r2 = fileResults[testName].find(row => row.name === "@m2d/react-markdown")?.ops ?? 0; - res1.push(r1); + res1.push(baseline); res2.push(r2); - res3.push(((r1 - r2) / r2) * 100); + res3.push(((r2 - baseline) / baseline) * 100); }); md.push(`~~~mermaid xychart-beta title "Render Speed Comparison (Ops/sec)" - x-axis ["${chart1Files.join('", "')}"] + x-axis ["${chart1Files.map((_, i) => i + 1).join('", "')}"] y-axis "Ops/sec (higher is better)" bar [${res1.join(", ")}] %% react-markdown bar [${res2.join(", ")}] %% @m2d/react-markdown @@ -62,11 +81,16 @@ xychart-beta md.push(`~~~mermaid xychart-beta title "Render Speed Comparison (Ops/sec)" - x-axis ["${chart1Files.join('", "')}"] + x-axis ["${chart1Files.map((_, i) => i + 1).join('", "')}"] y-axis "Δ from react-markdown (%)" line [${res3.join(", ")}] %% difference percent + line [${res3.map(() => 0).join(", ")}] %% Zero line ~~~\n`); + md.push( + `> **Labels:**\n> ${chart1Files.map((name, i) => `${i + 1}: ***${name}***;`).join("\n> ")}\n`, + ); + md.push(`Detailed Tables`); Object.entries(fileResults).forEach(([file, rows]) => { @@ -89,4 +113,5 @@ xychart-beta }); fs.writeFileSync(path.resolve("..", outPath), md.join("\n") + "\n", "utf8"); + fs.writeFileSync(path.resolve(logsDir, logsOutPath + ".md"), md.join("\n") + "\n", "utf8"); } diff --git a/lib/fixtures/medium-formatting.md b/lib/fixtures/formatting.md similarity index 100% rename from lib/fixtures/medium-formatting.md rename to lib/fixtures/formatting.md diff --git a/lib/fixtures/index.ts b/lib/fixtures/index.ts index 04a7b9b5..42262998 100644 --- a/lib/fixtures/index.ts +++ b/lib/fixtures/index.ts @@ -8,12 +8,12 @@ export const files = [ "short.md", "medium.md", "long.md", - "short-simple.md", - "medium-formatting.md", - "long-tutorial.md", + // "simple.md", + // "formatting.md", + // "tutorial.md", "gfm-complexity.md", "deeply-nested-lists.md", - "site-content.md", + // "site-content.md", ]; export const markdowns = files.map(file => fs.readFileSync(path.join(fixturesDir, file), "utf8")); diff --git a/lib/fixtures/short-simple.md b/lib/fixtures/simple.md similarity index 100% rename from lib/fixtures/short-simple.md rename to lib/fixtures/simple.md diff --git a/lib/fixtures/long-tutorial.md b/lib/fixtures/tutorial.md similarity index 100% rename from lib/fixtures/long-tutorial.md rename to lib/fixtures/tutorial.md diff --git a/lib/package.json b/lib/package.json index a3cf04a9..218ad690 100644 --- a/lib/package.json +++ b/lib/package.json @@ -2,7 +2,7 @@ "name": "@m2d/react-markdown", "author": "Mayank Kumar Chaudhari (https://mayank-chaudhari.vercel.app)", "private": false, - "version": "0.3.0", + "version": "1.0.0", "description": "A modern, SSR-friendly React Markdown renderer that preserves the MDAST tree for reuse (e.g., mdast2docx), supports full JSX children, unified plugins, and component overrides.", "license": "MPL-2.0", "main": "./dist/index.js", diff --git a/lib/src/server/index.ts b/lib/src/server/index.ts index 5801b7a5..b47b4423 100644 --- a/lib/src/server/index.ts +++ b/lib/src/server/index.ts @@ -5,6 +5,7 @@ */ // server component exports +export * from "./mdx"; export * from "./omit"; export * from "./unwrap"; export * from "./md"; diff --git a/lib/src/server/md/md.test.tsx b/lib/src/server/md/md.test.tsx index 83f75a22..7c1e3fb1 100644 --- a/lib/src/server/md/md.test.tsx +++ b/lib/src/server/md/md.test.tsx @@ -71,22 +71,6 @@ describe.concurrent("Md", () => { expect(ref.current[0].mdast.type).toBe("root"); }); - test("renders nested React elements with MarkdownRecursive", ({ expect }) => { - const testId = "md-root-" + crypto.randomUUID(); - render( - - - **Hare** - - - **Krishna** - - , - ); - const md = screen.getByTestId(testId); - expect(md?.textContent).toBe("HareKrishna"); - }); - test("supports remarkPlugins and rehypePlugins", async ({ expect }) => { const testId = "md-root-" + crypto.randomUUID(); const plugin = () => (tree: any) => { @@ -103,18 +87,4 @@ describe.concurrent("Md", () => { const md = screen.getByTestId(testId); expect(md.textContent).toContain("plugin!"); }); - - test("Handle children tree containing custom components", ({ expect }) => { - const testId = "md-root-" + crypto.randomUUID(); - const CustomComponent = ({ children }: any) => {children}; - render( - - - test - - , - ); - const md = screen.getByTestId(testId); - expect(md.querySelector("code")?.textContent).toBe("test"); - }); }); diff --git a/lib/src/server/md/md.tsx b/lib/src/server/md/md.tsx index b2b3debd..40575c6d 100644 --- a/lib/src/server/md/md.tsx +++ b/lib/src/server/md/md.tsx @@ -1,43 +1,5 @@ -import { IntrinsicProps, Markdown, MdProps, uuid } from "../../utils"; -import { isValidElement, ReactNode, Fragment } from "react"; - -interface MarkdownRecursiveProps { - children: ReactNode; - markdownProps: Omit; -} - -/** - * Recursively traverses React children and injects markdown rendering - * into string-based content, preserving JSX wrapper structure. - */ -const MarkdownRecursive = ({ children, markdownProps }: MarkdownRecursiveProps) => { - if (typeof children === "string") return {children}; - - if (Array.isArray(children)) { - const prefix = uuid(); - return children.map((child, id) => ( - - {child} - - )); - } - - if (isValidElement(children)) { - const Tag = children.type; - const innerProps = children.props as IntrinsicProps; - - return ( - - - {(innerProps as IntrinsicProps).children} - - - ); - } - // Non-string, non-element nodes are returned as-is - /* v8 ignore next 2 should never reach here, but in case */ - return children; -}; +import { Markdown, MdProps } from "../../utils"; +import { Fragment } from "react"; /** * The Markdown renderer component. @@ -63,8 +25,8 @@ export const Md = ({ return ( // @ts-expect-error - props are valid for HTML elements but cannot be statically inferred on Fragment - {children} - + ); }; diff --git a/lib/src/server/mdx/index.ts b/lib/src/server/mdx/index.ts new file mode 100644 index 00000000..20e33470 --- /dev/null +++ b/lib/src/server/mdx/index.ts @@ -0,0 +1,2 @@ +// component exports +export * from "./mdx"; diff --git a/lib/src/server/mdx/mdx.test.tsx b/lib/src/server/mdx/mdx.test.tsx new file mode 100644 index 00000000..a87b2f25 --- /dev/null +++ b/lib/src/server/mdx/mdx.test.tsx @@ -0,0 +1,122 @@ +import { cleanup, render, screen } from "@testing-library/react"; +import { afterEach, describe, test } from "vitest"; +import { Mdx } from "./mdx"; +import md from "../../../../sample.md?raw"; +import { uuid } from "../../utils"; + +describe.concurrent("Md", () => { + afterEach(cleanup); + + test("renders without errors and applies className", ({ expect }) => { + const clx = "my-class"; + const testId = "md-root"; + render( + + {md} + , + ); + expect(screen.getByTestId(testId).classList).toContain(clx); + }); + + test("renders markdown content as HTML", ({ expect }) => { + const testId = "md-root-1"; + render(**bold** _italic_); + const md = screen.getByTestId(testId); + expect(md.innerHTML).toContain(""); + expect(md.innerHTML).toContain(""); + }); + + test("renders with custom wrapper", ({ expect }) => { + const testId = "md-root-2"; + render( + + Hello + , + ); + const md = screen.getByTestId(testId); + expect(md.tagName.toLowerCase()).toBe("section"); + expect(md.textContent).toBe("Hello"); + }); + + test("renders with custom component for tag", ({ expect }) => { + const testId = "md-root-3"; + const CustomP = ({ children }: any) => {children}; + render({`Hello **World**`}); + expect(screen.getByTestId("custom-p").textContent).toBe("Hello World"); + }); + + test("skips HTML when skipHtml is true", ({ expect }) => { + const testId = "md-root-4"; + render({`raw test`}); + const md = screen.getByTestId(testId); + expect(md.innerHTML).not.toContain(""); + expect(md.textContent).toContain("raw test"); + }); + + test("skipHtml", ({ expect }) => { + const testId = "md-" + uuid(); + render( + {`Hello **world**\n\nSomething here`}, + ); + expect(screen.getByTestId(testId).textContent).toBe("Hello world"); + }); + + test("passes mdastRef with parsed mdast", ({ expect }) => { + const testId = "md-root-" + crypto.randomUUID(); + const ref = { current: null as any }; + render( + + # Title + , + ); + expect(ref.current).toBeTruthy(); + expect(ref.current[0].mdast.type).toBe("root"); + }); + + test("renders nested React elements with MarkdownRecursive", ({ expect }) => { + const testId = "md-root-" + crypto.randomUUID(); + render( + + + **Hare** + + + **Krishna** + + , + ); + const md = screen.getByTestId(testId); + expect(md?.textContent).toBe("HareKrishna"); + }); + + test("supports remarkPlugins and rehypePlugins", async ({ expect }) => { + const testId = "md-root-" + crypto.randomUUID(); + const plugin = () => (tree: any) => { + tree.children.push({ + type: "paragraph", + children: [{ type: "text", value: "plugin!" }], + }); + }; + render( + + test + , + ); + const md = screen.getByTestId(testId); + expect(md.textContent).toContain("plugin!"); + }); + + test("Handle children tree containing custom components", ({ expect }) => { + const testId = "md-root-" + crypto.randomUUID(); + const CustomComponent = ({ children }: any) => {children}; + render( + + + test + + , + ); + const md = screen.getByTestId(testId); + expect(md.querySelector("code")?.textContent).toBe("test"); + }); +}); diff --git a/lib/src/server/mdx/mdx.tsx b/lib/src/server/mdx/mdx.tsx new file mode 100644 index 00000000..a25b2d27 --- /dev/null +++ b/lib/src/server/mdx/mdx.tsx @@ -0,0 +1,79 @@ +import { IntrinsicProps, Markdown, MdxProps, uuid } from "../../utils"; +import { isValidElement, ReactNode, Fragment } from "react"; + +interface MarkdownRecursiveProps { + children: ReactNode; + markdownProps: Omit; +} + +/** + * Recursively traverses React children and injects markdown rendering + * into string-based content, preserving JSX wrapper structure. + */ +const MarkdownRecursive = ({ children, markdownProps }: MarkdownRecursiveProps) => { + if (typeof children === "string") return {children}; + + if (Array.isArray(children)) { + const prefix = uuid(); + return children.map((child, id) => ( + + {child} + + )); + } + + if (isValidElement(children)) { + const Tag = children.type; + const innerProps = children.props as IntrinsicProps; + + return ( + + + {(innerProps as IntrinsicProps).children} + + + ); + } + // Non-string, non-element nodes are returned as-is + /* v8 ignore next 2 should never reach here, but in case */ + return children; +}; + +/** + * The Markdown renderer component. + * Provides a safe, SSR-compatible way to render markdown with support for: + * - Custom wrappers + * - Plugin pipelines (remark + rehype) + * - Component overrides + * - Optional raw HTML stripping + */ +export const Mdx = ({ + children, + wrapper, + remarkPlugins, + rehypePlugins, + remarkRehypeOptions, + astRef, + components, + skipHtml, + ...props +}: MdxProps) => { + const Wrapper = wrapper ?? (Object.keys(props).length ? "div" : Fragment); + + return ( + // @ts-expect-error - props are valid for HTML elements but cannot be statically inferred on Fragment + + + {children} + + + ); +}; diff --git a/lib/src/utils.tsx b/lib/src/utils.tsx index 15bb93f9..8bedf81c 100644 --- a/lib/src/utils.tsx +++ b/lib/src/utils.tsx @@ -44,7 +44,7 @@ export type AstRef = { current?: AstArrayElement[] }; /** * Props accepted by the main `` component for rendering Markdown. */ -export interface MdProps extends HTMLProps { +export interface MdxProps extends HTMLProps { /** * Optional wrapper element. Defaults to `` if additional props are passed, otherwise uses `Fragment`. */ @@ -81,11 +81,8 @@ export interface MdProps extends HTMLProps { skipHtml?: boolean; } -interface MarkdownProps extends MdProps { - /** - * Raw markdown string to be parsed and rendered. - */ - children: string; +export interface MdProps extends MdxProps { + children?: string; } /** @@ -100,7 +97,7 @@ export const Markdown = ({ astRef, components, skipHtml, -}: MarkdownProps) => { +}: MdProps) => { const processor = unified() .use(remarkParse) .use(remarkPlugins) @@ -110,7 +107,7 @@ export const Markdown = ({ }) .use(rehypePlugins); - const mdast = processor.parse(children); + const mdast = processor.parse(children ?? ""); const hast = processor.runSync(mdast); if (astRef) { if (!astRef.current) astRef.current = []; diff --git a/packages/shared/CHANGELOG.md b/packages/shared/CHANGELOG.md index 358b0d38..21aa8062 100644 --- a/packages/shared/CHANGELOG.md +++ b/packages/shared/CHANGELOG.md @@ -1,5 +1,12 @@ # @repo/shared +## 0.0.6 + +### Patch Changes + +- Updated dependencies [344c4d2] + - @m2d/react-markdown@1.0.0 + ## 0.0.5 ### Patch Changes diff --git a/packages/shared/package.json b/packages/shared/package.json index dcbdfd1f..97f3a8d1 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@repo/shared", - "version": "0.0.5", + "version": "0.0.6", "private": true, "sideEffects": false, "main": "./dist/index.js", diff --git a/update.sh b/update.sh new file mode 100644 index 00000000..aaafa71a --- /dev/null +++ b/update.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +set -euo pipefail + +DEFAULT_ISSUE_KEY="#mayank1513" +DEFAULT_BASE_BRANCH="origin/main" + +if [[ $# -eq 0 ]]; then + echo "🔧 No arguments passed. You can override the defaults below:" + read -rp "Enter issue key [$DEFAULT_ISSUE_KEY]: " INPUT_ISSUE_KEY + read -rp "Enter base branch [$DEFAULT_BASE_BRANCH]: " INPUT_BASE_BRANCH + ISSUE_KEY="${INPUT_ISSUE_KEY:-$DEFAULT_ISSUE_KEY}" + BASE_BRANCH="${INPUT_BASE_BRANCH:-$DEFAULT_BASE_BRANCH}" +else + ISSUE_KEY="${1:-$DEFAULT_ISSUE_KEY}" + BASE_BRANCH="${2:-$DEFAULT_BASE_BRANCH}" +fi + +git fetch --prune + +DRY_RUN=false +if [[ "${3:-}" == "--dry-run" ]]; then + DRY_RUN=true + echo "🧪 Running in dry-run mode (no commits will be changed)" +fi + +echo "🔍 Using issue key: $ISSUE_KEY" +echo "🔁 Using base branch: $BASE_BRANCH" + +MERGE_BASE=$(git merge-base HEAD "$BASE_BRANCH") +echo "🔗 Merge-base with $BASE_BRANCH: $MERGE_BASE" + +if $DRY_RUN; then + echo "🔎 Commits that would be amended:" + git rev-list --reverse "$MERGE_BASE"..HEAD | while read -r COMMIT; do + MSG=$(git log -1 --pretty=%B "$COMMIT") + if [[ "$MSG" != *$ISSUE_KEY* ]]; then + SHORT_ID=$(git rev-parse --short "$COMMIT") + echo "✏️ $SHORT_ID: would amend with '$ISSUE_KEY: ' prefix" + fi + done +else + git rebase --exec "bash -c 'MSG=\$(git log -1 --pretty=%B); if [[ \"\$MSG\" != *$ISSUE_KEY* ]]; then echo \"Amending commit: \$(git rev-parse --short HEAD)\"; git commit --amend -m \"$ISSUE_KEY: \$MSG\" --no-edit --date=\"\$(git show -s --format=%ci)\" --no-gpg-sign; else echo \"Skipping commit: \$(git rev-parse --short HEAD) (already contains key)\"; fi'" --onto "$MERGE_BASE" "$MERGE_BASE" + + echo "✅ All matching commits have been updated with issue key prefix if needed." +fi
test
{children}