Skip to content

feat(orchestrator): reduce NFS Module Federation sync size - #4024

Open
lokanandaprabhu wants to merge 3 commits into
redhat-developer:mainfrom
lokanandaprabhu:orchestrator/reduce-nfs-sync-size
Open

feat(orchestrator): reduce NFS Module Federation sync size#4024
lokanandaprabhu wants to merge 3 commits into
redhat-developer:mainfrom
lokanandaprabhu:orchestrator/reduce-nfs-sync-size

Conversation

@lokanandaprabhu

Copy link
Copy Markdown
Member

Summary

  • Replace OrchestratorIcon (MUI SvgIcon) with inline SVG in alpha.tsx to remove MUI component infrastructure from the sync bundle
  • Extract widget rendering into FormDecoratorContent.tsx and dynamically import() it in FormWidgetsApi, moving the ~860 KB RJSF widget graph from sync to async — loaded only when a workflow form is opened
  • Both OFS and NFS paths benefit from the lazy loading

Bundle Impact

Plugin Export Before After Delta
orchestrator-form-widgets ./alpha (NFS) 1002.6 KB sync 112.7 KB sync -88.8%
orchestrator-form-widgets . (OFS) 917.1 KB sync 51.6 KB sync -94.4%
orchestrator ./alpha (NFS) 542.1 KB sync 524.0 KB sync -3.3%

Test plan

  • All 79 orchestrator-form-widgets tests pass
  • All 289 orchestrator tests pass
  • Bundle metrics captured before/after confirming size reductions
  • Verify plugin loads correctly in RHDH with NFS enabled

🤖 Generated with Claude Code

@rhdh-qodo-merge

rhdh-qodo-merge Bot commented Jul 28, 2026

Copy link
Copy Markdown

Code Review by Qodo

Grey Divider

Sorry, something went wrong

We weren't able to complete the code review on our side. Please try again manually by commenting /agentic_review on this PR.

Grey Divider

Qodo Logo

@rhdh-gh-app

rhdh-gh-app Bot commented Jul 28, 2026

Copy link
Copy Markdown

Changed Packages

Package Name Package Path Changeset Bump Current Version
@red-hat-developer-hub/backstage-plugin-orchestrator-form-widgets workspaces/orchestrator/plugins/orchestrator-form-widgets patch v1.12.0
@red-hat-developer-hub/backstage-plugin-orchestrator workspaces/orchestrator/plugins/orchestrator patch v5.10.0

@rhdh-qodo-merge

Copy link
Copy Markdown

PR Summary by Qodo

Lazy-load form widget graph and inline icon to shrink Module Federation sync bundles

✨ Enhancement 🧪 Tests ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Lazy-load the form decorator/widget graph so heavy RJSF code ships async only when forms open.
• Replace the MUI SvgIcon-based Orchestrator icon with an inline SVG to drop MUI icon plumbing.
• Add/adjust tests and publish patch changesets for orchestrator and form-widgets packages.
Diagram

sequenceDiagram
  participant UI as "Workflow form"
  participant API as "FormWidgetsApi"
  participant Loader as "import()"
  participant Content as "FormDecoratorContent"
  participant Form as "RJSF FormComponent"
  UI->>API: getFormDecorator()
  UI->>API: render Decorated(props)
  API->>Loader: import("./FormDecoratorContent")
  Loader-->>Content: default export
  API-->>UI: set state -> re-render
  UI->>Content: render(FormComponent, context)
  Content->>Form: render(widgets + validators + formContext)
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. React.lazy + Suspense boundary
  • ➕ More idiomatic lazy-loading pattern for components
  • ➕ Can show explicit loading UI instead of returning null
  • ➖ Requires adding/deciding a fallback UI and ensuring Suspense compatibility in the hosting tree
  • ➖ May complicate SSR/test setup depending on environment
2. Split widgets into a separately exported entrypoint/package
  • ➕ Clearer dependency boundary; consumers opt-in explicitly to heavy widgets
  • ➕ Can avoid runtime state/effect glue code
  • ➖ Requires API/consumer changes and documentation updates
  • ➖ Harder migration for existing OFS/NFS consumers expecting current API surface
3. Bundler-level chunking (splitChunks/externals) without code changes
  • ➕ Minimal code churn in runtime path
  • ➕ Keeps synchronous render behavior unchanged
  • ➖ More fragile across Module Federation hosts and build tool variations
  • ➖ Harder to guarantee that sync MF payload shrinks for both OFS and NFS

Recommendation: The PR’s approach (dynamic import cached on the API instance, with a small state/effect bridge) is a pragmatic way to guarantee the heavy RJSF widget graph moves out of the sync Module Federation bundle without changing the public API. If desired, a follow-up could replace the return null interim render with an explicit lightweight fallback (or migrate to React.lazy/Suspense) to make loading behavior clearer.

Files changed (5) +125 / -40

Enhancement (1) +26 / -36
FormWidgetsApi.tsxLazy-load FormDecoratorContent from FormWidgetsApi via dynamic import +26/-36

Lazy-load FormDecoratorContent from FormWidgetsApi via dynamic import

• Replaces eager imports of RJSF widget infrastructure with a cached 'import('./FormDecoratorContent')' promise. Uses component state + effect to render nothing until the async module resolves, then renders the extracted decorator content.

workspaces/orchestrator/plugins/orchestrator-form-widgets/src/FormWidgetsApi.tsx

Refactor (2) +84 / -2
FormDecoratorContent.tsxExtract decorator content (widgets/validation/context) into a lazy-loadable module +67/-0

Extract decorator content (widgets/validation/context) into a lazy-loadable module

• Introduces a new component that encapsulates widget registration, custom validation passthrough, and 'useGetExtraErrors()' wiring. This module is intended to be loaded asynchronously to keep the sync bundle small.

workspaces/orchestrator/plugins/orchestrator-form-widgets/src/FormDecoratorContent.tsx

alpha.tsxInline Orchestrator SVG icon to avoid MUI SvgIcon dependency in alpha export +17/-2

Inline Orchestrator SVG icon to avoid MUI SvgIcon dependency in alpha export

• Removes the 'OrchestratorIcon' (MUI 'SvgIcon') import and replaces the page icon with inline SVG markup. Reduces transitive MUI component infrastructure in the sync Module Federation bundle for the alpha entry.

workspaces/orchestrator/plugins/orchestrator/src/alpha.tsx

Tests (1) +9 / -2
FormWidgetsApi.test.tsxUpdate FormWidgetsApi test to handle async dynamic import/render +9/-2

Update FormWidgetsApi test to handle async dynamic import/render

• Makes the decoration test async, preloads the lazy module, and flushes microtasks via 'act()' to allow the import resolution and rerender. Preserves assertions that widgets/context/validators are passed to the underlying form component.

workspaces/orchestrator/plugins/orchestrator-form-widgets/src/FormWidgetsApi.test.tsx

Other (1) +6 / -0
lazy-load-nfs-sync.mdAdd changeset for sync bundle size reduction patches +6/-0

Add changeset for sync bundle size reduction patches

• Adds a changeset marking patch releases for orchestrator and orchestrator-form-widgets. Documents the intent to reduce NFS Module Federation sync size via lazy-loading.

workspaces/orchestrator/.changeset/lazy-load-nfs-sync.md

@rhdh-qodo-merge

Copy link
Copy Markdown

Preparing PR labels...

@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.00000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.88%. Comparing base (e03b281) to head (9bf2d58).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4024   +/-   ##
=======================================
  Coverage   57.87%   57.88%           
=======================================
  Files        2393     2394    +1     
  Lines       95985    96000   +15     
  Branches    26803    26787   -16     
=======================================
+ Hits        55551    55566   +15     
- Misses      38940    38943    +3     
+ Partials     1494     1491    -3     
Flag Coverage Δ *Carryforward flag
adoption-insights 84.54% <ø> (ø) Carriedforward from e03b281
ai-integrations 69.06% <ø> (ø) Carriedforward from e03b281
app-defaults 69.79% <ø> (ø) Carriedforward from e03b281
augment 46.67% <ø> (ø) Carriedforward from e03b281
boost 76.77% <ø> (ø) Carriedforward from e03b281
bulk-import 72.55% <ø> (ø) Carriedforward from e03b281
cost-management 13.55% <ø> (ø) Carriedforward from e03b281
dcm 60.72% <ø> (ø) Carriedforward from e03b281
extensions 56.48% <ø> (ø) Carriedforward from e03b281
global-floating-action-button 71.18% <ø> (ø) Carriedforward from e03b281
global-header 62.17% <ø> (ø) Carriedforward from e03b281
homepage 47.46% <ø> (ø) Carriedforward from e03b281
install-dynamic-plugins 56.77% <ø> (ø) Carriedforward from e03b281
intelligent-assistant 74.24% <ø> (ø) Carriedforward from e03b281
konflux 91.98% <ø> (ø) Carriedforward from e03b281
lightspeed 69.02% <ø> (ø) Carriedforward from e03b281
mcp-integrations 83.40% <ø> (ø) Carriedforward from e03b281
orchestrator 66.86% <92.00%> (+0.06%) ⬆️
quickstart 65.04% <ø> (ø) Carriedforward from e03b281
sandbox 79.56% <ø> (ø) Carriedforward from e03b281
scorecard 84.94% <ø> (ø) Carriedforward from e03b281
theme 87.90% <ø> (ø) Carriedforward from e03b281
translations 5.12% <ø> (ø) Carriedforward from e03b281
x2a 79.31% <ø> (ø) Carriedforward from e03b281

*This pull request uses carry forward flags. Click here to find out more.


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e03b281...9bf2d58. Read the comment docs.

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

@lokanandaprabhu

Copy link
Copy Markdown
Member Author

/cc @debsmita1

@openshift-ci
openshift-ci Bot requested a review from debsmita1 July 28, 2026 10:05
@lokanandaprabhu

Copy link
Copy Markdown
Member Author

Tested on app-next NFS shell (rhdh#5115)

  • Orchestrator page loads correctly with inline SVG icon in sidebar
  • Workflow form renders with all RJSF widgets (lazy-loaded via dynamic import)
  • Workflow execution completes successfully

Bundle impact (orchestrator-form-widgets ./alpha expose):

Metric Baseline Current Delta
Sync chunks 5 (1006.8 KB) 3 (112.7 KB) -2 chunks (-894.1 KB / -88.8%)
NFS vs OFS +1 chunks (+85.5 KB) -1 chunks (-808.6 KB) NFS now smaller than OFS

orchestrator-nfs-test

Comment thread workspaces/orchestrator/plugins/orchestrator-form-widgets/src/FormWidgetsApi.tsx Outdated
Comment thread workspaces/orchestrator/plugins/orchestrator/src/alpha.tsx Outdated
lokanandaprabhu and others added 3 commits July 29, 2026 11:20
Lazy-load heavy dependencies to reduce sync bundle size:
- Replace OrchestratorIcon (MUI SvgIcon) with inline SVG in alpha.tsx
- Extract widget rendering into FormDecoratorContent and dynamically
  import it in FormWidgetsApi, moving the ~860 KB RJSF widget graph
  from sync to async

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove unnecessary `import React from 'react'` in FormDecoratorContent
  and FormWidgetsApi, use named imports instead
- Move inline SVG from alpha.tsx back to OrchestratorIcon component,
  replacing MUI SvgIcon with plain <svg> element
- Update API reports

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@lokanandaprabhu
lokanandaprabhu force-pushed the orchestrator/reduce-nfs-sync-size branch from e3e5bfd to 9bf2d58 Compare July 29, 2026 06:00
@sonarqubecloud

Copy link
Copy Markdown

@lokanandaprabhu

Copy link
Copy Markdown
Member Author

@debsmita1 Updated the PR based on feedback, PTAL.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants