Chat: React.lazy/React.Suspense with secureboot integration, build improvements, dependency cleanup#156
Open
velkoff wants to merge 12 commits intomeganz:masterfrom
Open
Chat: React.lazy/React.Suspense with secureboot integration, build improvements, dependency cleanup#156velkoff wants to merge 12 commits intomeganz:masterfrom
React.lazy/React.Suspense with secureboot integration, build improvements, dependency cleanup#156velkoff wants to merge 12 commits intomeganz:masterfrom
Conversation
…ild improvements, dependency cleanup - introduced code-splitting via `React.lazy`/`React.Suspense` with 68% reduction of the initial bundle size - introduced `megaChunkLoader` mechanism to route lazy-loaded chunks through the `secureboot` integrity pipeline - migrated outstanding CommonJS to ES modules for better tree-shaking - introduced `ErrorBoundary` wrapping the chat to capture any uncaught errors in the component tree - disabled `splitChunks` and HMR to enforce deterministic, verified builds - removed unused `react-hot-loader` and style loaders (incl. 15 transitive build dependencies) - updated `build.sh` with extended build pipeline for the chat bundles - replaced shared static class properties in favor of shared constants/utilities for better tree-shaking
# Conflicts: # js/chat/bundle.js # js/chat/ui/conversations.jsx # package-lock.json # package.json
# Conflicts: # js/chat/bundle.js
…lazy-loaded prematurely
# Conflicts: # js/chat/bundle.js
# Conflicts: # package-lock.json # package.json
# Conflicts: # js/chat/bundle.js
# Conflicts: # js/chat/bundle.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Currently, the chat bundle is loaded entirely for all MEGA users, but non-trivial portion of them may never interact with the chat. This means that the webclient loads the 1.25 MB chat bundle upfront irrespective of whether given user opens conversation, starts meeting or uses any of the other chat features.
This pull request reduces the initial bundle size to 394 KB (-68%) by introducing lazy-loading via
React.lazy/React.Suspensethat integrates with the webclient’ssecurebootpipeline, ensuring all lazy-loaded chunks go through XHR + SHA-256 hash verification. Additional improvements include deprecating CommonJS instances in favor of ES modules for improved tree-shaking, removal of deprecated/unused dependencies.Main bundle
Initial bundle: 1,249 KB -> 394 KB (-68%)
Lazy-loaded chunks: 901 KB (7 chunks, loaded on-demand)
Total bundle size: 1,249 KB -> 1,291 KB (+3% overhead)
Note: measured from build artifacts, e.g. local build and uncompressed; live sizes differ due to the release packaging, hashing and compression. Relative reduction is assumed to hold, though.
Lazy-loaded chunks
core-ui(373 KB) — main chat/meetings UIcall(206 KB) — call UI, join workflow, loading statescontacts-panel(105 KB) — contacts panelcloud-browser(85 KB) — cloud browser dialogschedule-meeting(76 KB) — schedule meeting, recurring meetings behavior, edit occurrencesstart-conversation(39 KB) — start chat/meeting, contact selectors, group chat wizardwaiting-room(39 KB) — waiting rooms behavior, admit dialogThe current chunk boundaries are flexible and can be adjusted -- related chunks can be consolidated to reduce the total count and/or split differently to optimize for specific user flows. The current splitting prioritizes grouping components by user flow, as to avoid micro-splitting and network waterfalls. Also, the main bundle can be further shaved off (to ~150 KB), but it requires wider code changes.
React.lazy/React.Supsense+securebootReact.lazy()triggers__webpack_require__.l(url)megaChunkLoader.jsxintercepts and extracts the chunk name from the URLjsl2key, ex.:call->chat:call_jsM.require()and delegates to it the XHR + hash verification behaviorReact.Suspenseboundary renders the component; fails explicitly if nojsl2entry is present (default loader is intentionally not preserved as fallback)[see
megaChunkLoader.jsxfor further details]Additional build improvements and dependency cleanup
splitChunks: we want to enforce deterministic and predictable chunks; chunk boundaries are defined manually withwebpackChunkName, which allow us to ensure each chunk is known and verifiedHot Module Replacement(HMR,hot): hot updates bypass hash verification; ensures consistent behavior with the rest of thewebclientand allows us to avoid dynamically injected modules that are unverified at runtime, incl. during development__webpack_require__.lnot preserved as default fallback: chunks withoutjsl2entries fail hard rather than falling back to unverifiedscripttag injectionrequire()->importstatements throughout the chat codebase are migrated, as to improve webpack’s static analysis for tree-shakingErrorBoundary: wraps the whole chat and catches any uncaught errors in the component tree, not just chunk failures; provides retry/reload recovery behavior and prevents crashes from propagating and breaking the entire chat UIreact-hot-loader: unused (HMRwas handling hot reloads); additionally, the upstream is deprecated with the library in maintenance mode; removes 15 transitive dependencies from the buildsass-loader: redundant; theSCSSfiles are compiled via standalone CLIstyle-loader,css-loaderandless-loaderare not needed as the chat doesn't use dynamic CSS importsbuild.sh: extended build pipeline for the lazy chunks, replacesReact.createElementcalls and appliesJSX_alias (~2,879 calls, ~45 KB total reduction in total); validates the chunk registryLeftPanel.NAMESPACE,ContactsPanel.isVerified), which required the entire component to be imported just to access a constant -- this defeated tree-shaking since the whole class would be pulled into any module needing the constantTesting
ErrorBoundaryrecovery worksjsl2entry and confirm it's rejected bysecureboot