elastic / kibana

Your window into the Elastic Stack
https://www.elastic.co/products/kibana
Other
19.67k stars 8.23k forks source link

[ML] Async bundles are loaded on each page #189755

Open thomasneirynck opened 3 months ago

thomasneirynck commented 3 months ago

Async chunks of the ML and datavisualizer plugin bundles are loaded on all Kibana pages.

This is likely due to code being imported in the /public startup or setup cycle of the plugin, which could be loaded asynchronously instead.

This is similar issue like https://github.com/elastic/kibana/issues/189679.

To cut down on Dashboard startup time, we are looking to cut down the initial bundle load.

elasticmachine commented 3 months ago

Pinging @elastic/ml-ui (:ml)

walterra commented 1 month ago

Thanks for raising this issue, I started to look into this.

On main it currently looks like this on page load:

Image

For some of the bundles I see room for improvement. For example, we have some direct exports from plugins/ml/public/index.ts and plugins/ml/public/plugin.ts. We can try to get rid of them and move some stuff to packages.

I started experimenting with this on a draft PR here: https://github.com/elastic/kibana/pull/193761

So far I was able to get rid of 2 bundles and ~4KB (I'll continue working on this):

Image

For some of the bundles I'm not sure how we'd get rid of them on page load. These are the bundles related to registering stuff: UI Actions, Embeddables, Home features, cases attachments etc. All of this is done during plugin initialization. I suspect in that context we can work on optimizing the bundle sizes, but we'd never get rid of the completely. Do you agree? Or is there precendence for getting rid of those bundles in that context?

The ML plugin might be a bit of a special case, because in addition to its own UI it provides quite some integration points for Kibana and its solutions, that's why all the registering has to happen on page load. There are also plans on the Kibana side to allow to register UI actions async which should make possible for use to bring the loading bundle size down again.

walterra commented 3 weeks ago

I continued looking into this. I found the other comments stating that even if it increases the size of the page load bundle, we'd prefer now to avoid async imports to have just a single file for each plugin on page load.

With this in mind I worked on a PoC refactor to see how far we can get with this: https://github.com/elastic/kibana/pull/197967

First I changed all async imports on page load so we only load a single page load bundle for the ml plugin. This increased the bundle size from ~75KB to ~170KB.

Image

The main culprit is that we have to register UI actions, embeddables and a maps layer wher we previously used the dynamic imports. I then tried a mix of optimizing with deep imports, lazy loading components and services. This way I got the bundle size back down to ~98KB!!

Image

We also exported some stuff from plugins/ml/public/index.ts. I removed that to get the bundle size down, but the PoC doesn't fix everything in the other plugins which consume these exports, that's something for another time.

I'll leave the draft PR as is for now as a PoC to prove we can refactor this without the loading bundle size exploding too much. We'll break out optimizations into individual PRs then in the future.