flow: Development Mode Performance Regression 14.x vs 19
Update:
Further investigation https://github.com/vaadin/flow/issues/10281#issuecomment-802839323
| Topic | Pull Request |
|---|---|
| Service Worker Generation | https://github.com/vaadin/flow/pull/10361 (20.x / 7.x) & https://github.com/vaadin/flow/pull/10384 (19.x / 6.x) |
| Use transpileOnly option for ts-loader | https://github.com/vaadin/flow/pull/10656 (20.x / 7.x) & https://github.com/vaadin/flow/pull/10715 (19.x / 6.x) |
| Shipping precompiled JS | https://github.com/vaadin/flow/pull/10765 (20.x / 7.x) & https://github.com/vaadin/flow/pull/10795 (19.x / 6.x) |
Original Ticket:
Description of the bug / feature
Starting an application (v19) with mvn downloaded from start.vaadin.com takes a lot more time than the same application with v14. On my machine 3x slower…
Minimal reproducible example
V14 Example
- Download v14 app from https://start.vaadin.com
- Run it with
mvn - Application launches fast
Example attached: my-app(1).zip
V19 Example
- Download v19 app from https://start.vaadin.com
- Run it with
mvn - Application launches slow
Example attached: my-app(2).zip
Expected behavior
Both application have the same starting time.
Actual behavior
v14 - 7 sec webpack execution
2021-03-13 09:32:19.629 INFO 22488 --- [nio-8080-exec-1] c.v.f.s.DefaultDeploymentConfiguration :
Vaadin is running in DEBUG MODE.
When deploying application for production, remember to disable debug features. See more from https://vaadin.com/docs/
2021-03-13 09:32:21.440 INFO 22488 --- [nio-8080-exec-1] c.vaadin.flow.spring.SpringInstantiator : The number of beans implementing 'I18NProvider' is 0. Cannot use Spring beans for I18N, falling back to the default behavior
2021-03-13 09:32:26.009 INFO 22488 --- [ task-2] dev-webpack : Started webpack-dev-server. Time: 6972ms
v19 - 21 sec webpack execution (and a lot of unrelated logging)
2021-03-13 09:33:18.310 INFO 22804 --- [onPool-worker-1] com.vaadin.flow.server.DevModeHandler : Starting webpack-dev-server
------------------ Starting Frontend compilation. ------------------
2021-03-13 09:33:18.671 INFO 22804 --- [onPool-worker-1] com.vaadin.flow.server.DevModeHandler : Running webpack to compile frontend resources. This may take a moment, please stand by...
[....]
[2021-03-13 09:33:39.850 INFO 22804 --- [onPool-worker-1] com.vaadin.flow.server.DevModeHandler : Started webpack-dev-server. Time: 21539ms
Versions:
- Vaadin / Flow version: 14.x & 19.
- Java version: 8
- OS version: Ubuntu
- IDE (if applicable): Maven
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 24 (23 by maintainers)
I was able to reproduce and can confirm the issue. The frontend build time in v19 has increased 3.5x - 4x compared to that in v14.5.
webpack-dev-serverstartup time when running a default Flow project generated from https://start.vaadin.com:Projects: v14.zip, v16.zip, v17.zip, v18.zip, v19.zip.
Why it was not detected by an automatic regression test nor noticed by one of Vaadin developers is another question, but let’s focus at fixing the build time regression here. I could speculate, without having done a proper research, that the time increase could be due to (i) adding TypeScript compilation in V15 and (ii) adding Service Worker generation in V19. These are assumptions which need validation.
In Flow apps both TypeScript and Service Worker support bring little value, and the build time increase would be hard to justify if it is indeed due to adding these 2 features.
@haijian-vaadin Thanks! Haven’t noticed the other PR. Looks like my laptop got a little bit faster (20 vs 13 sec) with nothing else open, but still way behind v14 for me.
Same applications as last time, just changed the pom version to 14.5.3 and 19.0.6:
V14.4.9 2021-04-26 14:19:04.746 INFO 13669 — [ task-2] dev-webpack : Started webpack-dev-server. Time: 5934ms 2021-04-26 14:19:33.087 INFO 13880 — [ task-2] dev-webpack : Started webpack-dev-server. Time: 4865ms 2021-04-26 14:19:58.715 INFO 14089 — [ task-2] dev-webpack : Started webpack-dev-server. Time: 4958ms
V14.5.3 2021-04-26 14:26:49.007 INFO 14755 — [ task-2] dev-webpack : Started webpack-dev-server. Time: 5386ms 2021-04-26 14:27:15.730 INFO 14972 — [ task-2] dev-webpack : Started webpack-dev-server. Time: 5252ms 2021-04-26 14:27:38.519 INFO 15180 — [ task-2] dev-webpack : Started webpack-dev-server. Time: 5085ms
v19.0.3 2021-04-26 14:12:21.345 INFO 11717 — [onPool-worker-5] com.vaadin.flow.server.DevModeHandler : Started webpack-dev-server. Time: 14928ms 2021-04-26 14:13:00.762 INFO 11988 — [onPool-worker-3] com.vaadin.flow.server.DevModeHandler : Started webpack-dev-server. Time: 13966ms 2021-04-26 14:13:47.400 INFO 12217 — [onPool-worker-3] com.vaadin.flow.server.DevModeHandler : Started webpack-dev-server. Time: 13799ms
v19.0.6 2021-04-26 14:16:30.634 INFO 12882 — [onPool-worker-3] com.vaadin.flow.server.DevModeHandler : Started webpack-dev-server. Time: 11803ms 2021-04-26 14:17:24.555 INFO 13169 — [onPool-worker-3] com.vaadin.flow.server.DevModeHandler : Started webpack-dev-server. Time: 10705ms 2021-04-26 14:18:01.193 INFO 13390 — [onPool-worker-3] com.vaadin.flow.server.DevModeHandler : Started webpack-dev-server. Time: 11021ms
I researched for the performance improvement ideas using the https://github.com/stephencookdev/speed-measure-webpack-plugin when running
node node_modules/webpack/bin/webpack.js --mode=development.The starting numbers
Improvements
Recommend: using
{transpileOnly: true}option forts-loaderGives the best gain by far from the rest. In combination with
fork-ts-checker-webpack-pluginfor error checking:Before:
After:
Note: InjectManifest plugin time also decreases.
Recommend: removing
flow-frontend/**.tsfrom TypeScript compilationWe currently ship both source + compiled
.js+.d.tsfiles intarget/flow-frontendmodules, and the*.tssources are actually picked up for compilation because we haveresolve: { extensions: ['.ts', '.js'] }set in the generated webpack config. I tried simply swapping for['.js', '.ts']. This brings TypeScript module count down and improvests-loadertime even more.Before:
After:
The
.ts-first extensions configuration is the one recommended in webpack docs, however. We should consider removing the source.tsfiles from thetarget/flow-frontendas a way of doing this optimisation.Maybe: removing
resolve.modulesentriesWebpack docs recommend keeping those at minimum. We currently have
Removing the latter two was relatively easy in V20 Flow project from the starter for me. The
flowFrontendFolderentry was only necessary for the generated theme files, where we could replace it with the existingFrontend/directory alias, and the...projectStaticAssetsFolderswas never used.The impact of this is harder to measure with together other improvements applied, does not yield much to my eye. However, with default
ts-loadersetup, this seems to reduce total time for ~10%:Before:
After:
Maybe: skipping
InjectManifestpluginIn V20, the frontend build generates the service worker, whereas in V14 the service worker is served from Java runtime. Let us see how much it costs for frontend build time, and try skipping
InjectManifestplugin:Before:
After:
Again these numbers are taken without
ts-loaderimprovements applied. WithtranspileOnly: trueoption forts-loader, the impact was hardly noticeable for me.@knoobie thanks for sharing, good to see that it helps with the performance, we may need to do another round of performance tuning since the difference is still significant compare with v14.