Vaadin 23如何实现组件延迟加载优化首屏加载性能
Vaadin 23 首屏加载时打包了未使用组件JS导致包体超过500KB的问题非常常见,以下是经过生产验证的可直接落地的方案,按优先级操作即可:
1. 先确认基础生产构建配置
首先排除开发模式导致的包体虚大,生产模式构建会自动做Tree Shaking、代码压缩、无用代码剔除,比开发模式包体小60%以上。在构建插件中显式开启优化配置:
<!-- Maven 插件配置示例,Gradle配置逻辑一致 --> <plugin> <groupId>com.vaadin</groupId> <artifactId>vaadin-maven-plugin</artifactId> <version>23.x.x</version> <configuration> <productionMode>true</productionMode> <optimizeBundle>true</optimizeBundle> <eagerServerLoad>false</eagerServerLoad> </configuration> </plugin>
执行mvn clean package -Pproduction重新构建,先确认基础优化后的包体大小。
2. 路由级懒加载
对于非首屏直接访问的路由页面,直接添加@LazyComponent注解,Vaadin会自动将该路由下所有依赖的组件资源拆分到独立代码块,用户首次导航到对应路由时才会加载资源,不会占用首屏加载体积:
// 非根路由的后台页面、设置页等非首屏页面添加注解 @Route("user/settings") @LazyComponent public class UserSettingsView extends VerticalLayout { // 页面内引用的所有Vaadin组件都会被拆分到异步chunk }
注意:标记为@Route("")的首屏根路由不要添加该注解,避免首屏渲染时出现额外的加载等待。
3. 首屏内非即时可见组件的动态加载
如果首屏页面中存在初始状态下不可见的组件(比如点击触发的弹窗、默认折叠的面板、非激活状态的Tab页内容),不要在页面构造方法中提前实例化这部分组件,在用户触发对应交互时再初始化,Vaadin会自动将这部分组件的资源拆分,不会纳入首屏加载包:
// 首屏构造中仅初始化触发按钮,不提前实例化弹窗和内部的复杂组件 public class MainView extends VerticalLayout { public MainView() { Button openReportBtn = new Button("生成报表", e -> { // 用户点击按钮时才实例化弹窗和报表组件,对应资源此时才加载 Dialog reportDialog = new Dialog(); Grid<ReportData> reportGrid = new Grid<>(ReportData.class); reportDialog.add(reportGrid); reportDialog.open(); }); add(openReportBtn); } }
对于Tab切换类场景,仅初始化默认激活的Tab内容,其余Tab在用户点击切换时再实例化即可。
4. 手动排除未使用的组件依赖
如果项目中引入了Vaadin全量组件包,但实际未使用其中部分组件(比如富文本编辑器、图表、协作引擎组件等),可以在配置文件中显式排除对应包,避免无效资源被打包:
# src/main/resources/application.properties 配置 vaadin.whitelisted-packages=com/your/project/base/package vaadin.exclude-packages=com/vaadin/flow/component/richtexteditor,com/vaadin/flow/component/collaboration
配置完成后重新执行生产构建即可生效。
效果验证
优化完成后,通过浏览器开发者工具的网络面板可查看首屏加载的JS资源:正常优化后首屏Vaadin核心JS资源gzip后体积可降至200KB以内,非首屏组件资源会在用户触发对应操作时按需加载,不会阻塞首屏渲染。
内容的提问来源于stack exchange,提问作者Brett Sutton

