Skip to content

Commit

Permalink
[Dataset Quality] Optimize bundle size and chunks fragmentation (#194661
Browse files Browse the repository at this point in the history
)

## 📓 Summary

Closes #191602 

This work reduces the initial bundle size for the dataset quality plugin
by **~55%** and reduces fragmentation in the chunks when the main page
loads.

| Before | After |
|--------|--------|
| <img width="525" alt="Screenshot 2024-10-02 at 09 56 35"
src="https://github.com/user-attachments/assets/06fec02c-ff2c-4771-981f-a761bda67eae">
| <img width="521" alt="Screenshot 2024-10-02 at 09 59 16"
src="https://github.com/user-attachments/assets/a243b09a-9d83-4d0d-b875-20855bb18f5d">
|
| <img width="1398" alt="Screenshot 2024-10-02 at 09 56 55"
src="https://github.com/user-attachments/assets/66d2c131-b0b7-47e1-9a9a-e1be57e69bbb">
| <img width="678" alt="Screenshot 2024-10-02 at 09 58 59"
src="https://github.com/user-attachments/assets/39e6515e-5a83-4d97-97c8-cce01b7c6887">
|

Co-authored-by: Marco Antonio Ghiani <[email protected]>
  • Loading branch information
tonyghiani and Marco Antonio Ghiani authored Oct 2, 2024
1 parent 9bd0da6 commit ce8c9d8
Show file tree
Hide file tree
Showing 13 changed files with 118 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,22 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React, { useMemo } from 'react';
import { CoreStart } from '@kbn/core/public';
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { dynamic } from '@kbn/shared-ux-utility';
import { CoreStart } from '@kbn/core/public';
import { PerformanceContextProvider } from '@kbn/ebt-tools';
import { DatasetQualityContext, DatasetQualityContextValue } from './context';
import { useKibanaContextForPluginProvider } from '../../utils';
import { DatasetQualityStartDeps } from '../../types';
import React, { useMemo } from 'react';
import { DatasetQualityController } from '../../controller/dataset_quality';
import SummaryPanelProvider from '../../hooks/use_summary_panel';
import { ITelemetryClient } from '../../services/telemetry';
import { DatasetQualityStartDeps } from '../../types';
import { useKibanaContextForPluginProvider } from '../../utils';
import { DatasetQualityContext, DatasetQualityContextValue } from './context';
import EmptyStateWrapper from './empty_state/empty_state';
import Filters from './filters/filters';
import Header from './header';
import SummaryPanel from './summary_panel/summary_panel';
import Table from './table/table';
import Warnings from './warnings/warnings';

export interface DatasetQualityProps {
controller: DatasetQualityController;
Expand All @@ -25,45 +31,36 @@ export interface CreateDatasetQualityArgs {
telemetryClient: ITelemetryClient;
}

export const createDatasetQuality = ({
export const DatasetQuality = ({
controller,
core,
plugins,
telemetryClient,
}: CreateDatasetQualityArgs) => {
return ({ controller }: DatasetQualityProps) => {
const SummaryPanelProvider = dynamic(() => import('../../hooks/use_summary_panel'));
const KibanaContextProviderForPlugin = useKibanaContextForPluginProvider(core, plugins);
}: DatasetQualityProps & CreateDatasetQualityArgs) => {
const KibanaContextProviderForPlugin = useKibanaContextForPluginProvider(core, plugins);

const datasetQualityProviderValue: DatasetQualityContextValue = useMemo(
() => ({
service: controller.service,
telemetryClient,
}),
[controller.service]
);
const datasetQualityProviderValue: DatasetQualityContextValue = useMemo(
() => ({
service: controller.service,
telemetryClient,
}),
[controller.service, telemetryClient]
);

return (
<PerformanceContextProvider>
<DatasetQualityContext.Provider value={datasetQualityProviderValue}>
<SummaryPanelProvider>
<KibanaContextProviderForPlugin>
<DatasetQuality />
</KibanaContextProviderForPlugin>
</SummaryPanelProvider>
</DatasetQualityContext.Provider>
</PerformanceContextProvider>
);
};
return (
<PerformanceContextProvider>
<DatasetQualityContext.Provider value={datasetQualityProviderValue}>
<SummaryPanelProvider>
<KibanaContextProviderForPlugin>
<DatasetQualityContent />
</KibanaContextProviderForPlugin>
</SummaryPanelProvider>
</DatasetQualityContext.Provider>
</PerformanceContextProvider>
);
};

const Header = dynamic(() => import('./header'));
const Warnings = dynamic(() => import('./warnings/warnings'));
const EmptyStateWrapper = dynamic(() => import('./empty_state/empty_state'));
const Table = dynamic(() => import('./table/table'));
const Filters = dynamic(() => import('./filters/filters'));
const SummaryPanel = dynamic(() => import('./summary_panel/summary_panel'));

function DatasetQuality() {
function DatasetQualityContent() {
return (
<EuiFlexGroup direction="column" gutterSize="l">
<EuiFlexItem grow={false}>
Expand All @@ -72,7 +69,6 @@ function DatasetQuality() {
<EuiFlexItem grow={false}>
<Warnings />
</EuiFlexItem>

<EmptyStateWrapper>
<EuiFlexItem grow={false}>
<Filters />
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';
import { dynamic } from '@kbn/shared-ux-utility';
import type { CreateDatasetQualityArgs, DatasetQualityProps } from './dataset_quality';

export type { CreateDatasetQualityArgs, DatasetQualityProps };

const DatasetQuality = dynamic(() =>
import('./dataset_quality').then((mod) => ({ default: mod.DatasetQuality }))
);

export const createDatasetQuality = ({
core,
plugins,
telemetryClient,
}: CreateDatasetQualityArgs) => {
return ({ controller }: DatasetQualityProps) => {
return (
<DatasetQuality
controller={controller}
core={core}
plugins={plugins}
telemetryClient={telemetryClient}
/>
);
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { getDevToolsOptions } from '@kbn/xstate-utils';
import equal from 'fast-deep-equal';
import { distinctUntilChanged, from, map } from 'rxjs';
import { interpret } from 'xstate';
import { IDataStreamsStatsClient } from '../../services/data_streams_stats';
import { DataStreamsStatsServiceStart } from '../../services/data_streams_stats';
import {
createDatasetQualityControllerStateMachine,
DEFAULT_CONTEXT,
Expand All @@ -22,18 +22,20 @@ type InitialState = DatasetQualityPublicStateUpdate;

interface Dependencies {
core: CoreStart;
dataStreamStatsClient: IDataStreamsStatsClient;
dataStreamStatsService: DataStreamsStatsServiceStart;
}

export const createDatasetQualityControllerFactory =
({ core, dataStreamStatsClient }: Dependencies) =>
({ core, dataStreamStatsService }: Dependencies) =>
async ({
initialState = DEFAULT_CONTEXT,
}: {
initialState?: InitialState;
}): Promise<DatasetQualityController> => {
const initialContext = getContextFromPublicState(initialState ?? {});

const dataStreamStatsClient = await dataStreamStatsService.getClient();

const machine = createDatasetQualityControllerStateMachine({
initialContext,
toasts: core.notifications.toasts,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,33 @@ import equal from 'fast-deep-equal';
import { distinctUntilChanged, from, map } from 'rxjs';
import { interpret } from 'xstate';
import { createDatasetQualityDetailsControllerStateMachine } from '../../state_machines/dataset_quality_details_controller/state_machine';
import { IDataStreamsStatsClient } from '../../services/data_streams_stats';
import { IDataStreamDetailsClient } from '../../services/data_stream_details';
import { DataStreamsStatsServiceStart } from '../../services/data_streams_stats';
import { DataStreamDetailsServiceStart } from '../../services/data_stream_details';
import { DatasetQualityStartDeps } from '../../types';
import { getContextFromPublicState, getPublicStateFromContext } from './public_state';
import { DatasetQualityDetailsController, DatasetQualityDetailsPublicStateUpdate } from './types';

interface Dependencies {
core: CoreStart;
plugins: DatasetQualityStartDeps;
dataStreamStatsClient: IDataStreamsStatsClient;
dataStreamDetailsClient: IDataStreamDetailsClient;
dataStreamStatsService: DataStreamsStatsServiceStart;
dataStreamDetailsService: DataStreamDetailsServiceStart;
}

export const createDatasetQualityDetailsControllerFactory =
({ core, plugins, dataStreamStatsClient, dataStreamDetailsClient }: Dependencies) =>
({ core, plugins, dataStreamStatsService, dataStreamDetailsService }: Dependencies) =>
async ({
initialState,
}: {
initialState: DatasetQualityDetailsPublicStateUpdate;
}): Promise<DatasetQualityDetailsController> => {
const initialContext = getContextFromPublicState(initialState);

const [dataStreamStatsClient, dataStreamDetailsClient] = await Promise.all([
dataStreamStatsService.getClient(),
dataStreamDetailsService.getClient(),
]);

const machine = createDatasetQualityDetailsControllerStateMachine({
initialContext,
plugins,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,3 @@ export type { DatasetQualityPluginSetup, DatasetQualityPluginStart } from './typ
export function plugin(context: PluginInitializerContext<DatasetQualityConfig>) {
return new DatasetQualityPlugin(context);
}

export { datasetQualityAppTitle } from '../common/translations';
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ export class DatasetQualityPlugin
public start(core: CoreStart, plugins: DatasetQualityStartDeps): DatasetQualityPluginStart {
const telemetryClient = this.telemetry.start();

const dataStreamStatsClient = new DataStreamsStatsService().start({
const dataStreamStatsService = new DataStreamsStatsService().start({
http: core.http,
}).client;
});

const dataStreamDetailsClient = new DataStreamDetailsService().start({
const dataStreamDetailsService = new DataStreamDetailsService().start({
http: core.http,
}).client;
});

const DatasetQuality = createDatasetQuality({
core,
Expand All @@ -52,7 +52,7 @@ export class DatasetQualityPlugin

const createDatasetQualityController = createDatasetQualityControllerLazyFactory({
core,
dataStreamStatsClient,
dataStreamStatsService,
});

const DatasetQualityDetails = createDatasetQualityDetails({
Expand All @@ -64,8 +64,8 @@ export class DatasetQualityPlugin
const createDatasetQualityDetailsController = createDatasetQualityDetailsControllerLazyFactory({
core,
plugins,
dataStreamStatsClient,
dataStreamDetailsClient,
dataStreamStatsService,
dataStreamDetailsService,
});

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,31 @@
* 2.0.
*/

import { DataStreamDetailsClient } from './data_stream_details_client';
import {
DataStreamDetailsServiceSetup,
DataStreamDetailsServiceStartDeps,
DataStreamDetailsServiceStart,
IDataStreamDetailsClient,
} from './types';

export class DataStreamDetailsService {
constructor() {}
private client?: IDataStreamDetailsClient;

public setup(): DataStreamDetailsServiceSetup {}

public start({ http }: DataStreamDetailsServiceStartDeps): DataStreamDetailsServiceStart {
const client = new DataStreamDetailsClient(http);

return {
client,
getClient: () => this.getClient({ http }),
};
}

private async getClient({ http }: DataStreamDetailsServiceStartDeps) {
if (!this.client) {
const { DataStreamDetailsClient } = await import('./data_stream_details_client');
const client = new DataStreamDetailsClient(http);
this.client = client;
}

return this.client;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@
* 2.0.
*/

export * from './data_stream_details_client';
export * from './data_stream_details_service';
export * from './types';
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { Dashboard, DegradedFieldValues } from '../../../common/api_types';
export type DataStreamDetailsServiceSetup = void;

export interface DataStreamDetailsServiceStart {
client: IDataStreamDetailsClient;
getClient: () => Promise<IDataStreamDetailsClient>;
}

export interface DataStreamDetailsServiceStartDeps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,31 @@
* 2.0.
*/

import { DataStreamsStatsClient } from './data_streams_stats_client';
import {
DataStreamsStatsServiceSetup,
DataStreamsStatsServiceStartDeps,
DataStreamsStatsServiceStart,
IDataStreamsStatsClient,
} from './types';

export class DataStreamsStatsService {
constructor() {}
private client?: IDataStreamsStatsClient;

public setup(): DataStreamsStatsServiceSetup {}

public start({ http }: DataStreamsStatsServiceStartDeps): DataStreamsStatsServiceStart {
const client = new DataStreamsStatsClient(http);

return {
client,
getClient: () => this.getClient({ http }),
};
}

private async getClient({ http }: DataStreamsStatsServiceStartDeps) {
if (!this.client) {
const { DataStreamsStatsClient } = await import('./data_streams_stats_client');
const client = new DataStreamsStatsClient(http);
this.client = client;
}

return this.client;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@
* 2.0.
*/

export * from './data_streams_stats_client';
export * from './data_streams_stats_service';
export * from './types';
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { NonAggregatableDatasets } from '../../../common/api_types';
export type DataStreamsStatsServiceSetup = void;

export interface DataStreamsStatsServiceStart {
client: IDataStreamsStatsClient;
getClient: () => Promise<IDataStreamsStatsClient>;
}

export interface DataStreamsStatsServiceStartDeps {
Expand Down

0 comments on commit ce8c9d8

Please sign in to comment.