Skip to content

Improve Lighthouse Performance by Deferring Proto Block Initialization#5905

Open
stutijain2006 wants to merge 3 commits intosugarlabs:masterfrom
stutijain2006:PerformanceCore1
Open

Improve Lighthouse Performance by Deferring Proto Block Initialization#5905
stutijain2006 wants to merge 3 commits intosugarlabs:masterfrom
stutijain2006:PerformanceCore1

Conversation

@stutijain2006
Copy link
Contributor

This PR improves initial page load performance by deferring non-critical proto block initialization to idle time using requestIdleCallback.

Previously, all proto blocks (core + advanced) were initialized during Activity.init(), causing significant main-thread blocking during startup.
This change separates block initialization into:

  1. Core proto blocks → Initialized immediately (required for startup)
  2. Additional/advanced proto blocks → Deferred using requestIdleCallback

This reduces initial main-thread workload and improves Lighthouse performance metrics without affecting functionality.

What was Changed-

  • Split proto block initialization into:
  1. initCoreProtoBlocks()
  2. initAdvancedProtoBlocks()
  • Moved non-critical initialization into:
requestIdleCallback(() => {
    initAdvancedProtoBlocks(this);
});
  • Ensured palette regeneration and block loading logic remain intact.
  • Maintained backward compatibility with existing block structure.
  • Updated RequireJS module usage correctly.

Performance Impact-
Before-

  • Lighthouse Performance Score: ~60
  • Total Blocking Time: ~600 ms
  • Larger initial main-thread blocking
Screenshot 2026-02-25 234201 Screenshot 2026-02-25 234413

After-

  • Lighthouse Performance Score: 76
  • Total Blocking Time: 270 ms
  • Reduced startup blocking
  • Noticeably improved startup responsiveness
Screenshot 2026-02-25 233511 Screenshot 2026-02-25 233808

Functional Testing-
All major functionality has been manually tested and verified:

  • All palettes render correctly
  • Blocks drag/drop works
  • Beginner/advanced modes function correctly
  • File load/save works
  • Plugin load works
  • MIDI & ABC import works
  • Run / Stop / Step execution works
  • Resize & fullscreen behavior works
  • No console errors
  • No regression in UI behavior
    All existing functionality remains intact.

@github-actions
Copy link
Contributor

✅ All Jest tests passed! This PR is ready to merge.

@github-actions
Copy link
Contributor

✅ All Jest tests passed! This PR is ready to merge.

Copy link
Contributor

@7se7en72025 7se7en72025 left a comment

Choose a reason for hiding this comment

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

LGTM @walterbender .
Effectively optimizes the response time of the startup by moving the initialization of noncritical blocks to idle time, which decreases the total blocking time by 55% while providing a good fallback for compatibility.

@walterbender
Copy link
Member

One question: How did you determine which blocks were essential for statrtup?

@walterbender
Copy link
Member

Actually, a 2nd question as well. Why did you remove node from packages?

@stutijain2006
Copy link
Contributor Author

Actually, a 2nd question as well. Why did you remove node from packages?

I determined which blocks are essential by looking what actually is required during Activity.init() and initial palette rendering process. Any blocks that are needed to build default stack, render the palettes correctly or support beginner mode and project loading were treated as core and kept in the initial load. Blocks that are not referenced during startup and are only used when some specific palettes are opened were kept in additional.
So, the classification was based on the startup dependency flow.

Node was removed from the package as it should not be listed as an npm package dependency in the repository. Node.js is the runtime environment and is already provided by the system. Having node as dependency caused npm to install the node package, leading to a 403 error and smoke-test failure in the CI. Since the project does not require the npm node package itself, removing it resolves the installation error without affecting the functionality.

@walterbender
Copy link
Member

"to build default stack" ... what happens if the project loading at start up time is not the default stack -- a very common case.

re node, can you put that change in a separate PR (and please tag me)?

@stutijain2006
Copy link
Contributor Author

"to build default stack" ... what happens if the project loading at start up time is not the default stack -- a very common case.

re node, can you put that change in a separate PR (and please tag me)?

You're absolutely right, project loading at start is common scenario and not always the default stack. In the current implementation, core proto blocks required for initial rendering and block instantiation are initialized immediately, while non-critical and advanced blocks are deferred using requestIdleCallBack. I verified that project loading ( including saved projects, macros and plugins) continues to work correctly with this separation. The deferred blocks are not required during synchronous initialization path, and during testing, no race conditions or missing block definitions were observed. Still, if there are some edge cases where an advanced block must be available earlier, then I can adjust the classification accordingly.

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.

3 participants