LearnNewsExamplesServices
Frontmatter
id8379
titleImplement Lazy Loading Support for Main Thread Addons
stateClosed
labels
enhancementarchitectureperformancecore
assigneestobiu
createdAtJan 7, 2026, 1:36 PM
updatedAtJan 7, 2026, 2:22 PM
githubUrlhttps://github.com/neomjs/neo/issues/8379
authortobiu
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJan 7, 2026, 2:21 PM

Implement Lazy Loading Support for Main Thread Addons

Closed v11.19.0 enhancementarchitectureperformancecore
tobiu
tobiu commented on Jan 7, 2026, 1:36 PM

To optimize application startup time, we should allow Main Thread Addons to lazy-load their external dependencies (libraries) only when a remote method is actually called, rather than blocking initialization.

Proposed Changes:

  1. src/worker/mixin/RemoteMethodAccess.mjs

    • Update onRemoteMethod to check for a shouldInterceptRemote(methodName) method on the target instance.
    • If this returns true, the call is intercepted even if isReady is true.
  2. src/main/addon/Base.mjs

    • Add useLazyLoading config (default: false).
    • Update construct and initAsync: If useLazyLoading is true, initAsync should not await loadFiles(), allowing the addon to become "ready" immediately.
    • Implement shouldInterceptRemote(methodName): Return true if the library files are not yet loaded (i.e., loading promise is pending) and the method is in interceptRemotes.
    • Ensure onInterceptRemotes triggers the file loading (via cacheMethodCall -> executeLoadFiles).

Outcome: Addons configured with useLazyLoading: true will not block the main thread initialization. Their libraries will be fetched and executed only when the first remote method (e.g., render) is invoked.

tobiu added the enhancement label on Jan 7, 2026, 1:36 PM
tobiu added the architecture label on Jan 7, 2026, 1:36 PM
tobiu added the performance label on Jan 7, 2026, 1:36 PM
tobiu added the core label on Jan 7, 2026, 1:36 PM
tobiu assigned to @tobiu on Jan 7, 2026, 2:21 PM
tobiu closed this issue on Jan 7, 2026, 2:21 PM
tobiu
tobiu Jan 7, 2026, 2:22 PM

Input from Gemini 3 Pro:

✦ ## Implementation Summary & Architectural Enhancements

This ticket evolved into a significant architectural update to support efficient, non-blocking addon initialization and robust configuration inheritance.

1. Lazy Loading for Main Thread Addons

We introduced a mechanism to defer the loading of external libraries (like Mermaid.js) until they are actually needed, significantly improving application startup time.

  • Neo.main.addon.Base: Added useLazyLoading config.
    • When true, the addon's construct method leaves the #loadFilesPromise in a pending state.
    • This causes initAsync() to pause after remote registration but before completion. Critically, this does not block the Main Thread (which only waits for remotesReady()), but it keeps the addon's isReady state as false.
    • Interception as Trigger: Since isReady is false, RemoteMethodAccess automatically intercepts incoming remote calls (e.g., render). The interception logic (cacheMethodCall) detects the pending promise and triggers loadFiles(). Once loaded, the promise resolves, initAsync completes, isReady becomes true, and the cached call executes.

2. Core Enhancement: deepArrays Merge Strategy

To support robust lazy loading, we needed to ensure the loadFiles method (defined in Neo.main.addon.Base) remains accessible as a remote method even when subclasses (like Mermaid) define their own remote configs. Previously, Neo.merge (used by merge: 'deep') replaced arrays, causing the base loadFiles remote definition to be lost.

  • Neo.mjs: Added Neo.mergeDeepArrays(target, source). This utility performs a deep merge on objects but concatenates and deduplicates arrays instead of replacing them.
  • Neo.mergeConfig: Updated to support a new strategy string: 'deepArrays'.
  • Neo.core.Config: Documented the new strategy.

3. Base Class Updates

  • Neo.core.Base: Updated the remote_ config descriptor to use merge: 'deepArrays'. This ensures that remote definitions accumulate down the inheritance chain.
  • Neo.main.addon.Base: Added loadFiles to the remote config. Thanks to the new merge strategy, this method is now automatically exposed for all addons, allowing for manual preloading from the App worker if desired.

4. Pilot Implementation: Mermaid Addon

The Neo.main.addon.Mermaid addon was updated to utilize useLazyLoading: true.

  • It no longer blocks startup.
  • It automatically loads the Mermaid library upon the first render call.
  • It inherits the loadFiles remote endpoint correctly.

These changes provide a scalable pattern for integrating heavy third-party libraries without compromising the initial load performance of Neo.mjs applications.

jonnyamsp referenced in commit cf34f44 - "feat: Implement Lazy Loading and Deep Array Merging on Jan 7, 2026, 2:25 PM