Skip to content

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

Open
lokanandaprabhu wants to merge 2 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 2 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

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>
@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

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@rhdh-qodo-merge

Copy link
Copy Markdown

Preparing PR labels...

@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.66667% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.81%. Comparing base (eb13368) to head (e3e5bfd).
⚠️ Report is 4 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4024   +/-   ##
=======================================
  Coverage   57.80%   57.81%           
=======================================
  Files        2393     2393           
  Lines       95919    95934   +15     
  Branches    26776    26761   -15     
=======================================
+ Hits        55448    55463   +15     
  Misses      38935    38935           
  Partials     1536     1536           
Flag Coverage Δ *Carryforward flag
adoption-insights 84.54% <ø> (ø) Carriedforward from eb13368
ai-integrations 69.06% <ø> (ø) Carriedforward from eb13368
app-defaults 69.79% <ø> (ø) Carriedforward from eb13368
augment 46.67% <ø> (ø) Carriedforward from eb13368
boost 75.92% <ø> (ø) Carriedforward from eb13368
bulk-import 72.55% <ø> (ø) Carriedforward from eb13368
cost-management 13.55% <ø> (ø) Carriedforward from eb13368
dcm 60.72% <ø> (ø) Carriedforward from eb13368
extensions 56.48% <ø> (ø) Carriedforward from eb13368
global-floating-action-button 71.18% <ø> (ø) Carriedforward from eb13368
global-header 62.17% <ø> (ø) Carriedforward from eb13368
homepage 47.54% <ø> (ø) Carriedforward from eb13368
install-dynamic-plugins 56.77% <ø> (ø) Carriedforward from eb13368
intelligent-assistant 74.06% <ø> (ø) Carriedforward from eb13368
konflux 91.98% <ø> (ø) Carriedforward from eb13368
lightspeed 69.02% <ø> (ø) Carriedforward from eb13368
mcp-integrations 83.40% <ø> (ø) Carriedforward from eb13368
orchestrator 66.86% <91.66%> (+0.06%) ⬆️
quickstart 65.04% <ø> (ø) Carriedforward from eb13368
sandbox 79.56% <ø> (ø) Carriedforward from eb13368
scorecard 84.94% <ø> (ø) Carriedforward from eb13368
theme 83.89% <ø> (ø) Carriedforward from eb13368
translations 5.12% <ø> (ø) Carriedforward from eb13368
x2a 79.31% <ø> (ø) Carriedforward from eb13368

*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 eb13368...e3e5bfd. 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

* limitations under the License.
*/

import React from 'react';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is not needed

* limitations under the License.
*/

import React from 'react';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is not needed

title: 'Orchestrator',
icon: <OrchestratorIcon />,
icon: (
<svg

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Use the OrchestratorIcon import, just replace the OrchestratorIcon content with this one

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