Skip to content

Add Linkedom Node target#157

Open
pedraal wants to merge 2 commits intokepano:mainfrom
pedraal:linkedom
Open

Add Linkedom Node target#157
pedraal wants to merge 2 commits intokepano:mainfrom
pedraal:linkedom

Conversation

@pedraal
Copy link

@pedraal pedraal commented Mar 11, 2026

Summary

This MR aims to offer a more performant target for node env and make some global performance improvements.
The current defuddle/node uses JSDOM which is quite slow vs Linkedom. The former being already used for Cloudflare Worker target.

Changes

  • Create a defuddle/linkedom export target, inspired of the defuddle/node and what is done in website/src/convert.ts to patch missing APIs in Linkedom.
  • Precompile regexes to avoid recompiling them on every parse calls
  • Scope post processing to the selected main content element

Benchmark

Here are the results I've observed by running defuddle/node vs defuddle/linkedom on a Macbook pro M3 with node v24.12.0

Running 58 fixtures × 5 runs each…
..........................................................

Fixture JSDOM (ms) linkedom (ms) speedup
codeblocks--mintlify 35.9 11.3 3.18x
codeblocks--rehype-pretty-code 12.4 2.4 5.09x
codeblocks--rockthejvm.com:articles:kotlin-101-type-classes 18.7 4.1 4.57x
codeblocks--stripe 55.4 17.0 3.26x
comments--news.ycombinator.com:item?id=12345678 36.8 8.9 4.12x
comments--old.reddit.com:r:test:comments:abc123:test_post 35.0 8.8 3.99x
elements--complex-tables 22.7 5.5 4.16x
elements--data-table 14.0 3.2 4.34x
elements--embedded-videos 16.2 2.2 7.32x
elements--farsi-zwnj 10.0 2.3 4.36x
elements--javascript-links 8.8 1.8 4.89x
elements--lazy-image 35.8 11.6 3.08x
elements--nbsp-handling 6.3 1.4 4.66x
elements--whitespace-newlines 7.4 1.5 4.79x
footnotes--maggieappleton.com-xanadu-patterns 112.6 31.7 3.55x
general--12gramsofcarbon.com:p:ilyas-30-papers-to-carmack-vlaes 92.3 30.7 3.00x
general--apnews-link-enhancement 7.7 1.3 6.09x
general--appendix-heading 9.5 1.9 4.92x
general--cp4space-jordan-algebra 21.6 5.6 3.86x
general--daringfireball.net:2025:02:the_iphone_16e 54.4 13.8 3.94x
general--developer.mozilla.org:en-US:docs:Web:JavaScript:Reference:Global_Objects:Array 12.0 2.7 4.44x
general--github.com-issue-56 117.0 43.3 2.70x
general--github.com:test-owner:test-repo:pull:42 18.5 4.5 4.11x
general--lesswrong.com:s:N7nDePaNabJdnbXeE:p:vJFdjigzmcXMhNTsx 277.1 64.5 4.29x
general--multi-article-portfolio 12.2 3.0 4.11x
general--news.ycombinator.com:item?id=12345678 24.1 5.9 4.07x
general--obsidian.md:blog:verify-obsidian-sync-encryption 28.7 6.6 4.36x
general--react-streaming-ssr 6.4 1.0 6.22x
general--scp-wiki.wikidot.com-scp-9935 20.7 6.4 3.21x
general--stephango.com-buy-wisely 22.8 5.8 3.94x
general--substack-app 58.4 24.9 2.35x
general--tailwind-hidden-blog-index 25.5 6.2 4.09x
general--wikipedia 86.4 26.1 3.31x
general--www.figma.com:blog:introducing-codex-to-figma 50.7 15.5 3.26x
general--x.com-article-2026-02-13 225.3 82.9 2.72x
general--x.com-article 9.5 2.3 4.13x
hidden--nodes 6.6 1.4 4.90x
hidden--visibility 9.3 1.5 6.32x
issues--106-menu-id 8.2 1.6 5.07x
issues--114-leading-hr 8.2 2.0 4.20x
issues--120-dhammatalks-footnotes 29.4 8.1 3.64x
issues--131-category-links 8.8 1.8 4.95x
issues--132-hero-class 10.5 1.6 6.70x
issues--136-time-element 8.5 1.6 5.33x
issues--141-arxiv-equation-tables 31.9 7.2 4.40x
issues--142-arxiv-multi-citations 21.3 5.8 3.64x
issues--143-arxiv-cross-references 12.5 2.7 4.56x
issues--144-arxiv-footnote-marks 17.2 4.6 3.70x
math--katex-centraliser 165.8 57.4 2.89x
math--katex 58.8 17.6 3.33x
math--mathjax-tex-scripts 9.0 2.0 4.55x
math--mathjax 206.2 64.0 3.22x
math--temml 43.8 13.1 3.34x
math--wikipedia-mathml 22.6 5.1 4.46x
scoring--related-posts-byline 12.9 3.7 3.45x
scoring--table-with-links 22.7 5.4 4.20x
table-layout--paulgraham.com-makersschedule 18.6 4.8 3.89x
table-layout--single-column 15.1 2.9 5.27x
Total 2356.3 684.6 3.44x

Testing

  • A tests/linkedom.test.ts is added to ensure it is running over existing fixtures (even though it is not checking that the content is the expected one) and that it is preserving the same API as defuddle/node target

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant