vaadin / flow

Vaadin Flow is a Java framework binding Vaadin web components to Java. This is part of Vaadin 10+.
Apache License 2.0
590 stars 164 forks source link

Remove the fallback bundle logic #15929

Closed Artur- closed 1 year ago

Artur- commented 1 year ago

Describe your motivation

When compiling the frontend, Flow scans all entry points (routes and exported web components) and determines which components are reachable/imported through those entry points. The frontend files (JS/CSS) related to all found components are then added to target/frontend/generated-flow-imports.js and that becomes the main JS bundle. All other components found on the classpath are then added to target/frontend/generated-flow-imports-fallback.js in case they are needed even though the component scanner found no reference to them. Then there is JS written to generated-flow-imports.js so that the fallback bundle can be dynamically imported.

This whole complexity is added so that even if you use components only through reflection (super rare) or if there is a bug in the component scanner (which then should be fixed), then your production bundle will still contain all the components you use.

The whole world fallback bundle causes bad performance if a single component is left out, for one reason or another. Then you end up in loading the whole fallback bundle, possibly even on the initial load, just because one file is misplaced. In this case you would get much better performance by defining explicitly that the one file is needed and all the other files would be left out.

The whole world fallback also causes the production build for smaller applications to be much slower than necessary. Typically it is one or several of the large components you are not using (charts/spreadsheet/...) and they take the most time to process in build.

Describe the solution you'd like

Instead of "just in case" adding the whole world in a fallback bundle we should make it clear which components are included in the bundle so you can somehow verify that the list contains the component you use. If you use components only through reflection or if there is a bug in the scanner, you are able to add components to the included list by adding @Uses(TheComponent.class) to any entry point or class reached by any entry point.

Legioth commented 1 year ago

One thing we could consider doing to limit the impact of removing the fallback bundle is to make the error handling clearer in the case when a component is missing from the bundle.

Artur- commented 1 year ago

We seem to already include this in a production build stats.json

{
 "bundleImports": [
  "@vaadin-component-factory/vcf-nav",
  "@vaadin/app-layout/theme/lumo/vaadin-app-layout.js",
  "@vaadin/app-layout/theme/lumo/vaadin-drawer-toggle.js",
  "@vaadin/button/theme/lumo/vaadin-button.js",
  "@vaadin/common-frontend/ConnectionIndicator.js",
  "@vaadin/horizontal-layout/theme/lumo/vaadin-horizontal-layout.js",
  "@vaadin/notification/theme/lumo/vaadin-notification.js",
  "@vaadin/polymer-legacy-adapter/style-modules.js",
  "@vaadin/scroller/theme/lumo/vaadin-scroller.js",
  "@vaadin/text-field/theme/lumo/vaadin-text-field.js",
  "@vaadin/tooltip/theme/lumo/vaadin-tooltip.js",
  "@vaadin/vaadin-lumo-styles/color-global.js",
  "@vaadin/vaadin-lumo-styles/sizing.js",
  "@vaadin/vaadin-lumo-styles/spacing.js",
  "@vaadin/vaadin-lumo-styles/style.js",
  "@vaadin/vaadin-lumo-styles/typography-global.js",
  "@vaadin/vaadin-lumo-styles/vaadin-iconset.js",
  "@vaadin/vertical-layout/theme/lumo/vaadin-vertical-layout.js",
  "Frontend/generated/jar-resources/flow-component-renderer.js"
 ],
}

so if a @JsModule or similar is found and it is not in the bundleImport list, there is a problem that can be logged as an error

vaadin-bot commented 1 year ago

This ticket/PR has been released with Vaadin 24.1.0.