Skip to content
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

[Maps] Code split Maps app #64594

Merged
merged 22 commits into from
May 4, 2020
Merged

Conversation

thomasneirynck
Copy link
Contributor

@thomasneirynck thomasneirynck commented Apr 27, 2020

Closes #64317


Code-split the maps-plugin to reduce the initial maps.plugin.js size.

There are two main code dependencies in the plugin-init that are the root cause of the large bundle size.

  1. Moves the load_layer_wizard dependency from the plugin-initialization to the GisMap component. GisMap wraps the entire application UX, including the add-layer-wizard. The layer wizards only need to be available there.
  2. Lazy loads the dependencies of the Maps-embeddable. The MapEmbeddableFactory needs to be registered at plugin-initialization. However, this module imports a lot of core-application code because of its redux-selector dependencies. By code-splitting here, we avoid pulling in the entire Maps-app in the main bundle

This reduces the maps.plugin size from 5+MB to around 300kb.

$ ls -lh x-pack/plugins/maps/target/public/
total 75048
-rw-r--r--  1 thomasneirynck  staff   2.0M Apr 29 16:57 1.plugin.js
-rw-r--r--  1 thomasneirynck  staff   349K Apr 29 16:57 1990c3d0f490fa881871c5779ab8c212.js
-rw-r--r--  1 thomasneirynck  staff   1.8M Apr 29 16:57 2.plugin.js
-rw-r--r--  1 thomasneirynck  staff   178K Apr 29 16:57 3.plugin.js
-rw-r--r--  1 thomasneirynck  staff   220K Apr 29 16:57 4.plugin.js
-rw-r--r--  1 thomasneirynck  staff   299K Apr 29 16:57 40cd439cda90e7f7f4135b4037835e37.png
-rw-r--r--  1 thomasneirynck  staff   178K Apr 29 16:57 5.plugin.js
-rw-r--r--  1 thomasneirynck  staff   822K Apr 29 16:57 6.plugin.js
-rw-r--r--  1 thomasneirynck  staff    21K Apr 29 16:57 7.plugin.js
-rw-r--r--  1 thomasneirynck  staff   202K Apr 29 16:57 e3b1bd3256c6e2785c1c7786bf60a1a7.js
-rw-r--r--  1 thomasneirynck  staff   129K Apr 29 16:57 f01a207f57de9c098b15d34197acd75c.png
-rw-r--r--  1 thomasneirynck  staff   225K Apr 29 16:57 maps.plugin.js
-rw-r--r--  1 thomasneirynck  staff    30M Apr 29 16:57 stats.json

Not sure if we really need to preserve the <Suspense> loading of the React-components. I can leave it/remove.

todo:

  • fix TS type errors
  • functional test failure

WIP - just a POC

@restrry I'll need some guidance on where to exactly introduce this. You referred to the MapViewComponent
(

class MapViewComponent extends Component {
)
in #64317 (comment), but this is just the code for the inspector.

I introduced it a little closer to the actual map, but that isn't really making any dent in the bundle size.

@thomasneirynck thomasneirynck added chore WIP Work in progress [Deprecated-Use Team:Presentation]Team:Geo Former Team Label for Geo Team. Now use Team:Presentation v8.0.0 v7.8.0 labels Apr 27, 2020
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-gis (Team:Geo)

@mshustov
Copy link
Contributor

mshustov commented Apr 28, 2020

I'll need some guidance on where to exactly introduce this. You referred to the MapViewComponent

Yeah, the rule of thumb is the higher Lazy component will be in the react tree the better.
With your changes, I still can see data plugin, @elastic/ems, @elastic/maki, d3 packages present in the initial bundle.
Also, I can see you register a bunch of Layer Wizards. Their React Components can be loaded asynchronously or you can alter renderWizard function to work with promises as well.

@joshdover
Copy link
Contributor

Did not have much time today to try solutions, but I confirmed removing the import { registerLayerWizards } from './layers/load_layer_wizards'; import drops the maps bundle by ~60%.

I'm not sure when these need to be registered. Does this just need to be called before the embeddable renders and before the application mounts? If so, I think we can drop an async import in the embeddable rendering code.

@thomasneirynck
Copy link
Contributor Author

I'm not sure when these need to be registered

Before the embeddable renders is sufficient, so it doesn't need to be in Plugin#start I think. I'll investigate.

import { HomePublicPluginSetup } from '../../../../src/plugins/home/public';
import { VisualizationsSetup } from '../../../../src/plugins/visualizations/public';
import { MAP_SAVED_OBJECT_TYPE } from '../common/constants';
import { MapEmbeddableFactory } from './embeddable';
import { MapEmbeddableFactory } from './embeddable/map_embeddable_factory';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't pull from the index.ts file as it brings in the actual Embeddable. Just pull in the factory.

@thomasneirynck thomasneirynck changed the title [Maps] POC lazy load container [Maps] Code split Maps app Apr 29, 2020
@thomasneirynck thomasneirynck marked this pull request as ready for review April 29, 2020 21:25
@thomasneirynck thomasneirynck requested a review from a team as a code owner April 29, 2020 21:25
@kindsun
Copy link
Contributor

kindsun commented Apr 30, 2020

Pretty interesting stuff. Left some minor comments. Need to dig into this a bit more to understand some of the details.Thanks for taking this one on! 🤾‍♂️

@thomasneirynck thomasneirynck requested a review from a team April 30, 2020 19:37
Copy link
Contributor

@nreese nreese left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for shrinking the maps plugin initial install size.

Can you remove the lazy load for MBMapContainer. Since this is used within GisMap, lazy loading GisMap will be sufficient.

Also can you remove gis_map/shim/index.ts and just change gis_map/index.ts to return default export

@justinkambic
Copy link
Contributor

From the Uptime side I ran this locally and our map shows up like normal 👍

Not going to LGTM because it looks like the review/work for the feature is ongoing still.

@rylnd
Copy link
Contributor

rylnd commented Apr 30, 2020

As of 231fb6d this is looking good on the SIEM side, but I'll double-check once this branch settles.

Nice bundle! 👍
Screenshot_4_30_20__3_58_PM

@thomasneirynck
Copy link
Contributor Author

@elasticmachine merge upstream

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

Copy link
Contributor

@nreese nreese left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm
code review, tested in chrome and firefox

@thomasneirynck thomasneirynck removed the WIP Work in progress label May 4, 2020
Copy link
Contributor

@rylnd rylnd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked this out again just now: from SIEM's perspective, things look/function as expected! 👍

Copy link
Contributor

@joshdover joshdover left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! I don't see any more obvious opportunities to split anything else out of the main bundle (which is now only 46kb gzipped!)

Copy link
Contributor

@justinkambic justinkambic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Uptime, the map still LGTM 👍

@thomasneirynck thomasneirynck merged commit 7bf7174 into elastic:master May 4, 2020
thomasneirynck added a commit to thomasneirynck/kibana that referenced this pull request May 5, 2020
Code-split the maps-plugin to reduce the initial `maps.plugin.js` size.

There were two main code dependencies in the plugin initialization that were the root cause of the large bundle size.

- `GisMap` wraps the entire application UX, including the add-layer-wizard. The layer wizards only need to be available there. This PR moves the `load_layer_wizard` dependency from the plugin-initialization to the `GisMap` component. 
- The `MapEmbeddableFactory` needs to be registered at plugin-initialization. However, this module imports a lot of core-application code. By code-splitting here, we avoid pulling in the entire Maps-app in the main bundle.

This also  introduces a lazy-initialization of the `GisMap` itself as an additional split to further reduce size of the bundles.
thomasneirynck added a commit that referenced this pull request May 5, 2020
* [Maps] Code split Maps app (#64594)

Code-split the maps-plugin to reduce the initial `maps.plugin.js` size.

There were two main code dependencies in the plugin initialization that were the root cause of the large bundle size.

- `GisMap` wraps the entire application UX, including the add-layer-wizard. The layer wizards only need to be available there. This PR moves the `load_layer_wizard` dependency from the plugin-initialization to the `GisMap` component. 
- The `MapEmbeddableFactory` needs to be registered at plugin-initialization. However, this module imports a lot of core-application code. By code-splitting here, we avoid pulling in the entire Maps-app in the main bundle.

This also  introduces a lazy-initialization of the `GisMap` itself as an additional split to further reduce size of the bundles.

* fix merge

Co-authored-by: Elastic Machine <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
chore [Deprecated-Use Team:Presentation]Team:Geo Former Team Label for Geo Team. Now use Team:Presentation release_note:skip Skip the PR/issue when compiling release notes v7.8.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Reduce maps bundle size (code splitting)
9 participants