-
Notifications
You must be signed in to change notification settings - Fork 75
docs(documentation): Add RFC 0019 Bundle-Info Preload #1194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
RandomByte
wants to merge
5
commits into
main
Choose a base branch
from
rfc-bundle-info-preload
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
569e3d3
docs(documentation): Add RFC 0019 Bundle Info Preload
RandomByte d1c6438
docs(documentation): Document manifest version implications
RandomByte d70e8ec
docs(documentation): Address review comments
RandomByte 07f50ae
docs(documentation): Update RFC template
RandomByte 728ca11
docs(documentation): Fix API name
RandomByte File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| - Start Date: 2025-11-17 | ||
| - RFC PR: [#1194](https://github.com/UI5/cli/pull/1194) | ||
| - Issue: - | ||
| - Affected components <!-- Check affected components by writing an "X" into the brackets --> | ||
| + [x] [builder](./packages/builder) | ||
| + [ ] [server](./packages/server) | ||
| + [ ] [cli](./packages/cli) | ||
| + [ ] [fs](./packages/fs) | ||
| + [ ] [project](./packages/project) | ||
| + [ ] [logger](./packages/logger) | ||
|
|
||
|
|
||
| # RFC 0019 Bundle Info Preload | ||
|
|
||
| ## Summary | ||
|
|
||
| This RFC proposes a new bundling approach for UI5 libraries called "Bundle-Info Preload". Instead of a single monolithic `library-preload.js`, each library will be split into two bundles: | ||
|
|
||
| 1. `library-preload.js`: A small initial bundle containing the `library.js`, its direct dependencies, as well as "bundle-info" describing the content of the second bundle | ||
| 2. `_library-content.js`: A larger secondary bundle containing the remaining modules of the library. | ||
|
|
||
| This allows the UI5 runtime to always load the small `library-preload.js` for all declared library dependencies, including those marked as "lazy". The larger `_library-content.js` is only loaded on-demand when a module from within it is actually requested. This new mechanism eliminates the need for application developers to manually trigger the loading of lazy dependencies. | ||
|
|
||
| ## Motivation | ||
|
|
||
| Currently, UI5 applications often declare library dependencies as "lazy" in their `manifest.json` to improve initial loading times. However, this requires developers to explicitly load these libraries using `sap/ui/core/Lib.load({name: "sap.m"})` (or the deprecated variant `sap.ui.getCore().loadLibrary("sap.m")`) before any of their modules can be used. This is a manual and error-prone process. | ||
|
|
||
| By splitting the library preload, the essential part of a library can be loaded eagerly without a significant performance penalty. The UI5 loader can then automatically fetch the larger part of the library when it's first needed. | ||
|
|
||
| This leads to the following benefits: | ||
| - **Simplified Application Development:** Developers no longer need to manually manage the loading of lazy library dependencies. | ||
| - **Improved Performance:** The large content bundle is only requested if the library is actually used, improving startup performance for applications with many optional dependencies. | ||
| - **Efficient Parallel Loading:** This concept fits well with the "manifest-first" loading strategy, enabling more efficient and parallel loading of dependencies. | ||
|
|
||
| ## Detailed design | ||
|
|
||
| The implementation of "Bundle-Info Preload" shall be handled by the UI5 CLI, specifically in the `builder` package. | ||
|
|
||
| ### Bundling Process | ||
|
|
||
| For any given UI5 library, the build process shall generate two bundles instead of one: | ||
|
|
||
| 1. **`library-preload.js`**: This bundle shall contain: | ||
| * The library's `library.js` file. | ||
| * All transitive dependencies of `library.js` that are part of the same library. | ||
| * A "bundle-info" section. This metadata informs the UI5 loader about which modules are contained in the second bundle. | ||
| 2. **`_library-content.js`**: This bundle shall contain all other productive JavaScript modules of the library that are not included in the `library-preload.js`. The leading underscore in the name indicates that this file is intended for framework internal use. Application developers should not expect the existence of this file and should not reference it directly. | ||
|
|
||
| A future UI5 CLI major release shall make this new bundling the default behavior for all UI5 libraries, regardless of the UI5 version they are built for. Existing custom bundle definitions for `library-preload.js` will be respected and will overrule this default behavior. | ||
|
|
||
| ### Manifest Flag | ||
|
|
||
| To allow the UI5 runtime to identify libraries built with this new approach, the UI5 CLI will add a new attribute to the library's `manifest.json` file: | ||
|
|
||
| ```json | ||
| { | ||
| "sap.ui5": { | ||
| "library": { | ||
| "bundleVersion": 2 | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| The presence of `"bundleVersion": 2` signals to the UI5 runtime that the library uses the "Bundle-Info Preload" format. The runtime can then safely and efficiently load the `library-preload.js` bundles for any lazy dependencies. If this flag is absent, the runtime can assume a legacy bundling format and issue a warning or error, as it expects all libraries for UI5 2.0+ to be built with a compatible UI5 CLI version. | ||
|
|
||
| Note that this manifest attribute will only be added in a later manifest version. Therefore, the UI5 CLI must also adapt the manifest version accordingly when building libraries. | ||
|
|
||
| ### Planned Runtime Behavior | ||
|
|
||
| In a future UI5 framework release the following behavior might be implemented. Note that the detailed design for this is out of scope of this RFC, which rather focuses on the UI5 CLI implementation. | ||
|
|
||
| 1. The application's `manifest.json` is loaded first. | ||
| 2. The UI5 runtime analyzes the library dependencies. | ||
| 3. For every library dependency (eager or lazy), it requests the corresponding `library-preload.js` as well as the `manifest.json` | ||
| 4. The UI5 loader checks the presence of the `"bundleVersion": 2` flag in the library's manifest and produces an error in case it is missing. | ||
| 5. When application code requests a module from a library for the first time, the UI5 loader checks the bundle-info from the already loaded `library-preload.js`. | ||
| 6. If the module is located in the secondary bundle, the loader requests the `_library-content.js` file and then provides the requested module. Subsequent requests for modules from that bundle are served directly from the loaded bundle similar to the "legacy" `library-preload.js`. | ||
|
|
||
| ### Handling `manifest.json` in `library-preload.js` | ||
|
|
||
| To support manifest-first loading in modern UI5 versions, the `manifest.json` of a library will **not** be included in its `library-preload.js` when building for UI5 2.0 and higher. For older UI5 1.x versions, the `manifest.json` will still be included to ensure compatibility, as these versions do not support manifest-first loading for libraries. | ||
|
|
||
| UI5 CLI shall attempt to detect the target UI5 version based on the version of the project's `sap.ui.core` dependency. If no such dependency is present, it should fallback to include the `manifest.json`, since this will only create little overhead and ensures compatibility with older UI5 versions. | ||
|
|
||
| ## How we teach this | ||
|
|
||
| The "Bundle-Info Preload" feature is designed to work transparently for most developers. The primary audience for this change is UI5 framework developers and library developers that work with custom bundle definitions. | ||
|
|
||
| **Terminology:** | ||
| - **Initial/Primary Bundle:** The new, smaller `library-preload.js`. | ||
| - **Content/Secondary Bundle:** The `_library-content.js` file. | ||
|
|
||
| **Documentation:** | ||
| - The UI5 CLI documentation for the `build` command should be updated to explain the new default bundling strategy. | ||
|
|
||
| ## Drawbacks | ||
|
|
||
| UI5 releases prior to version 1.74 do not provide all required UI5 loader features, making the new bundling incompatible with these versions. Developers still targeting older releases (such as 1.71) will need to be able to disable the new bundling behavior, or be provided with a long-term maintenance version of UI5 CLI v4, which continues to use the legacy bundling strategy. | ||
|
|
||
| Similarly, the addition of the manifest flag requires the use of a specific minimum manifest version which might not be supported by older UI5 releases. This might cause problems if any validation is done on the final manifest, e.g. during deployment or at runtime. | ||
|
|
||
| Another drawback is the introduction of an additional request for the `_library-content.js` file. However, this request only occurs if the library is actually used, and it happens in parallel with other requests. For libraries that are declared but never used, this approach saves bandwidth by not loading the large content bundle at all. For eagerly used libraries, the performance impact is expected to be negligible and outweighed by the benefits of parallel loading and simplified development. | ||
|
|
||
| There is also a minor risk of confusion if developers are not aware of the new bundling and are surprised by the presence of the `_library-content.js` file. Clear documentation will be key to mitigating this. | ||
|
|
||
| ## Alternatives | ||
|
|
||
| 1. Keep the status quo: Continue to require manual loading of lazy dependencies. This does not solve the underlying usability problem. | ||
| 2. Configuration Flag: Introduce a `ui5.yaml` configuration flag to enable or disable this feature. This would add unnecessary complexity. We are currently not aware of any significant drawbacks to using this new bundling with older UI5 versions (1.74 and later, see above), making a flag mostly redundant. | ||
| 3. Different Heuristics: Use other heuristics, like the project's `specVersion` or `manifest.json` version, to decide which bundling to apply. These are not reliable indicators of the target UI5 runtime version and would lead to a more complex and less predictable system. Always applying the new bundling is simpler and more robust. | ||
|
|
||
| ## Unresolved Questions and Bikeshedding | ||
|
|
||
| *This section should be removed (i.e. resolved) before merging* | ||
|
|
||
| - Final confirmation from colleagues on the name and location of the manifest flag (`"sap.ui5".library.bundleVersion`) as well as the required minimum manifest version | ||
| - Clarification on how the new manifest version can be used in old UI5 versions | ||
| - Clarification on how UI5 1.71 development can still be supported | ||
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What manifest version would that be? A 2.x version? Can there be side-effects when a manifest version is updated during the build? What about a bump from 1.x to 2.x?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't really judge on that. Looping in @codeworrior, @loginger, @H4ze
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, a 2.x version - the first 2.x version that lists the flag in the schema. For libraries, the schema version is not used as a switch at runtime, so I don't expect side effects when bumping it from 1.x to 2.x.
BTW: for many libs (especially. all framework libs) the manifest is anyhow generated.