Skip to content

Commit

Permalink
[Security Solution] Reduce initial bundle size (elastic#78992)
Browse files Browse the repository at this point in the history
* Load the redux store factory and initial state factory lazily
* Combine certain dynamic imports to reduce total async bundle size (this works because shared dependencies between async chunks are not being de-duped by Webpack.)
* Add explicit types in some areas.

Co-authored-by: Xavier Mouligneau <189600+XavierM@users.noreply.github.com>
  • Loading branch information
Robert Austin and XavierM committed Oct 13, 2020
1 parent 959cc1b commit 3244fa3
Show file tree
Hide file tree
Showing 7 changed files with 296 additions and 253 deletions.
14 changes: 2 additions & 12 deletions x-pack/plugins/security_solution/public/app/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,10 @@
*/

import React from 'react';
import { Store, Action } from 'redux';
import { render, unmountComponentAtNode } from 'react-dom';

import { AppMountParameters } from '../../../../../src/core/public';
import { State } from '../common/store';
import { StartServices } from '../types';
import { SecurityApp } from './app';
import { AppFrontendLibs } from '../common/lib/lib';

interface RenderAppProps extends AppFrontendLibs, AppMountParameters {
services: StartServices;
store: Store<State, Action>;
SubPluginRoutes: React.FC;
}
import { RenderAppProps } from './types';

export const renderApp = ({
apolloClient,
Expand All @@ -27,7 +17,7 @@ export const renderApp = ({
services,
store,
SubPluginRoutes,
}: RenderAppProps) => {
}: RenderAppProps): (() => void) => {
render(
<SecurityApp apolloClient={apolloClient} history={history} services={services} store={store}>
<SubPluginRoutes />
Expand Down
17 changes: 16 additions & 1 deletion x-pack/plugins/security_solution/public/app/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,27 @@ import {
Reducer,
AnyAction,
Middleware,
Action,
Store,
Dispatch,
PreloadedState,
StateFromReducersMapObject,
CombinedState,
} from 'redux';

import { AppMountParameters } from '../../../../../src/core/public';
import { StartServices } from '../types';
import { AppFrontendLibs } from '../common/lib/lib';

/**
* The React properties used to render `SecurityApp` as well as the `element` to render it into.
*/
export interface RenderAppProps extends AppFrontendLibs, AppMountParameters {
services: StartServices;
store: Store<State, Action>;
SubPluginRoutes: React.FC;
}

import { State, SubPluginsInitReducer } from '../common/store';
import { Immutable } from '../../common/endpoint/types';
import { AppAction } from '../common/store/actions';
Expand All @@ -31,7 +46,7 @@ export interface SecuritySubPlugin {
storageTimelines?: Pick<TimelineState, 'timelineById'>;
}

type SecuritySubPluginKeyStore =
export type SecuritySubPluginKeyStore =
| 'hosts'
| 'network'
| 'timeline'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

/**
* the plugin (defined in `plugin.tsx`) has many dependencies that can be loaded only when the app is being used.
* By loading these later we can reduce the initial bundle size and allow users to delay loading these dependencies until they are needed.
*/

import { renderApp } from './app';
import { composeLibs } from './common/lib/compose/kibana_compose';

import { createStore, createInitialState } from './common/store';

export { renderApp, composeLibs, createStore, createInitialState };
32 changes: 32 additions & 0 deletions x-pack/plugins/security_solution/public/lazy_sub_plugins.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

/**
* the plugin (defined in `plugin.tsx`) has many dependencies that can be loaded only when the app is being used.
* By loading these later we can reduce the initial bundle size and allow users to delay loading these dependencies until they are needed.
*/

import { Detections } from './detections';
import { Cases } from './cases';
import { Hosts } from './hosts';
import { Network } from './network';
import { Overview } from './overview';
import { Timelines } from './timelines';
import { Management } from './management';

/**
* The classes used to instantiate the sub plugins. These are grouped into a single object for the sake of bundling them in a single dynamic import.
*/
const subPluginClasses = {
Detections,
Cases,
Hosts,
Network,
Overview,
Timelines,
Management,
};
export { subPluginClasses };
Loading

0 comments on commit 3244fa3

Please sign in to comment.