Skip to content

feat: introduce lazy generators#609

Open
ovflowd wants to merge 4 commits intomainfrom
feat/lazy-generators
Open

feat: introduce lazy generators#609
ovflowd wants to merge 4 commits intomainfrom
feat/lazy-generators

Conversation

@ovflowd
Copy link
Member

@ovflowd ovflowd commented Feb 15, 2026

This PR increases performance and reduces complexity at module load time as we only load the generators and its dependencies as we need them, reducing strain on workers and Node.js module resolution.

@ovflowd ovflowd requested a review from a team as a code owner February 15, 2026 17:22
Copilot AI review requested due to automatic review settings February 15, 2026 17:22
@vercel
Copy link

vercel bot commented Feb 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
api-docs-tooling Ready Ready Preview Feb 16, 2026 0:50am

Request Review

@codecov
Copy link

codecov bot commented Feb 15, 2026

Codecov Report

❌ Patch coverage is 86.02151% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.62%. Comparing base (a8aacc8) to head (b0c5469).

Files with missing lines Patch % Lines
src/generators.mjs 0.00% 7 Missing ⚠️
src/generators/index.mjs 76.92% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #609      +/-   ##
==========================================
- Coverage   78.66%   78.62%   -0.04%     
==========================================
  Files         128      128              
  Lines       12456    12461       +5     
  Branches      883      902      +19     
==========================================
  Hits         9798     9798              
- Misses       2653     2658       +5     
  Partials        5        5              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link

github-actions bot commented Feb 15, 2026

api-links Generator

apilinks.json
Expected values to be strictly deep-equal:
+ actual - expected
... Skipped lines

  {
    'Agent.defaultMaxSockets': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_agent.js#L227',
    'Buffer.alloc': 'https://github.com/nodejs/node/blob/HEAD/lib/buffer.js#L431',
    'Buffer.allocUnsafe': 'https://github.com/nodejs/node/blob/HEAD/lib/buffer.js#L445',
    'Buffer.allocUnsafeSlow': 'https://github.com/nodejs/node/blob/HEAD/lib/buffer.js#L457',
...
    'agent.addRequest': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_agent.js#L292',
+   'agent.createConnection': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_agent.js#L231',
-   'agent.createConnection': 'https://github.com/nodejs/node/blob/HEAD/lib/https.js#L326',
    'agent.createSocket': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_agent.js#L363',
    'agent.destroy': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_agent.js#L595',
+   'agent.getName': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_agent.js#L261',
-   'agent.getName': 'https://github.com/nodejs/node/blob/HEAD/lib/https.js#L484',
    'agent.keepSocketAlive': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_agent.js#L552',
    'agent.removeSocket': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_agent.js#L491',
    'agent.reuseSocket': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_agent.js#L588',
    'assert.assert': 'https://github.com/nodejs/node/blob/HEAD/lib/assert.js#L185',
    'asyncResource.asyncId': 'https://github.com/nodejs/node/blob/HEAD/lib/async_hooks.js#L242',
...
    'server.address': 'https://github.com/nodejs/node/blob/HEAD/lib/net.js#L2297',
+   'server.close': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L611',
+   'server.closeAllConnections': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L621',
+   'server.closeIdleConnections': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L633',
-   'server.close': 'https://github.com/nodejs/node/blob/HEAD/lib/net.js#L2430',
-   'server.closeAllConnections': 'https://github.com/nodejs/node/blob/HEAD/lib/https.js#L120',
-   'server.closeIdleConnections': 'https://github.com/nodejs/node/blob/HEAD/lib/https.js#L122',
    'server.getConnections': 'https://github.com/nodejs/node/blob/HEAD/lib/net.js#L2392',
    'server.listen': 'https://github.com/nodejs/node/blob/HEAD/lib/net.js#L2114',
    'server.ref': 'https://github.com/nodejs/node/blob/HEAD/lib/net.js#L2535',
+   'server.setTimeout': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L649',
-   'server.setTimeout': 'https://github.com/nodejs/node/blob/HEAD/lib/https.js#L124',
    'server.unref': 'https://github.com/nodejs/node/blob/HEAD/lib/net.js#L2544',
+   'server[SymbolAsyncDispose]': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L617',
+   'server[undefined]': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L656',
-   'server[SymbolAsyncDispose]': 'https://github.com/nodejs/node/blob/HEAD/lib/net.js#L2470',
-   'server[undefined]': 'https://github.com/nodejs/node/blob/HEAD/lib/net.js#L2499',
    'serverresponse._finish': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L244',
    'serverresponse._implicitHeader': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L351',
    'serverresponse.assignSocket': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L294',
    'serverresponse.detachSocket': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L305',
    'serverresponse.statusCode': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L267',

orama-db Generator

File Base Head Diff
orama-db.json 8.03 MB 8.03 MB -1.00 B (-0.00%)

@ovflowd
Copy link
Member Author

ovflowd commented Feb 15, 2026

cc @nodejs/web-infra

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request introduces lazy loading for generators to improve module load time performance and reduce strain on Node.js module resolution. Instead of eagerly importing all generators at module load time, generators are now loaded on-demand using dynamic imports.

Changes:

  • Converted all generator imports to lazy loaders using dynamic import() wrapped in a lazyDefault helper
  • Updated type definitions to handle Promise-wrapped generator loaders with new LazyGenerator and ResolvedGenerator types
  • Modified all generator consumers to properly await lazy-loaded generators

Reviewed changes

Copilot reviewed 8 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/generators/index.mjs Replaced direct imports with lazy loaders using dynamic import() for all 16 generators
src/generators/types.d.ts Added LazyGenerator and ResolvedGenerator type helpers to properly type lazy-loaded generators
src/utils/configuration/types.d.ts Updated Configuration type to use ResolvedGenerator for accessing defaultConfiguration
src/utils/configuration/index.mjs Made getDefaultConfig async and updated to await generator loading when accessing defaultConfiguration
src/utils/configuration/tests/index.test.mjs Updated mock generators to return async functions instead of direct objects
src/threading/parallel.mjs Made createParallelWorker async to await generator loading
src/threading/chunk-worker.mjs Updated to await generator loading before accessing processChunk
src/threading/tests/parallel.test.mjs Added await to all createParallelWorker calls in tests
src/generators/tests/index.test.mjs Updated tests to properly resolve lazy generators before assertions
src/generators.mjs Updated scheduleGenerator to await generator loading; properly handles async worker creation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Aviv Keller <me@aviv.sh>
@AugustinMauroy
Copy link
Member

This PR increases performance

Do you have stat on that ?

@ovflowd
Copy link
Member Author

ovflowd commented Feb 16, 2026

Benchmark Results

Command: node bin/cli.mjs generate -t web -t orama-db -i ../node/doc/api/*.md -o out --index ../node/doc/api/index.md
Tool: hyperfine 1.20.0 (5 runs, 1 warmup)
Environment: Node.js v24.13.0, Linux

--threads 1 (single-threaded)

Metric main feat/lazy-generators Δ
Mean 18.787s ± 0.772s 18.848s ± 0.619s +0.3%
Median 18.507s 18.595s +0.5%
Min 18.202s 18.499s +1.6%
Max 20.133s 19.945s -0.9%
User time 30.057s 29.954s -0.3%
System time 1.028s 1.031s +0.3%
Peak memory 4,806 MB 4,758 MB -1.0%

--threads 4

Metric main feat/lazy-generators Δ
Mean 14.232s ± 0.109s 13.902s ± 0.181s -2.3%
Median 14.197s 13.935s -1.8%
Min 14.105s 13.653s -3.2%
Max 14.385s 14.134s -1.7%
User time 40.818s 39.344s -3.6%
System time 1.565s 1.597s +2.0%
Peak memory 6,443 MB 6,540 MB +1.5%

Default threads (system CPUs)

Metric main feat/lazy-generators Δ
Mean 14.064s ± 0.339s 13.812s ± 0.365s -1.8%
Median 14.018s 13.714s -2.2%
Min 13.737s 13.567s -1.2%
Max 14.584s 14.447s -0.9%
User time 51.736s 48.278s -6.7%
System time 2.376s 1.890s -20.5%
Peak memory 8,665 MB 7,801 MB -10.0%

Summary

  • Single-threaded: Performance is effectively identical — no regression.
  • 4 threads: feat/lazy-generators is ~2.3% faster wall-clock, with 3.6% less CPU time.
  • Default threads (all CPUs): feat/lazy-generators is ~1.8% faster wall-clock, with 6.7% less CPU user time and ~10% lower peak memory.

The lazy generators approach shows consistent modest improvements in multi-threaded scenarios, with the biggest wins in reduced CPU time and memory usage at higher thread counts.

@ovflowd
Copy link
Member Author

ovflowd commented Feb 16, 2026

(Interestingly enough my initial tests yesterday were wildly different with this PR branch being almost 6-7 seconds faster, but hey, a win is a win.


assert.equal(result.addedIn, 'v1.0.0');
assert.equal(result.readingTime, '1 min read');
assert.equal(result.readingTime, '5 min read');
Copy link
Member

Choose a reason for hiding this comment

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

is this change expected? seems odd

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.

4 participants