[8.x] [Dataset Quality] Optimize bundle size and chunks fragmentation (#194661) (#194746)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Dataset Quality] Optimize bundle size and chunks fragmentation
(#194661)](https://github.com/elastic/kibana/pull/194661)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Marco Antonio
Ghiani","email":"marcoantonio.ghiani01@gmail.com"},"sourceCommit":{"committedDate":"2024-10-02T16:37:04Z","message":"[Dataset
Quality] Optimize bundle size and chunks fragmentation (#194661)\n\n## 📓
Summary\r\n\r\nCloses #191602 \r\n\r\nThis work reduces the initial
bundle size for the dataset quality plugin\r\nby **~55%** and reduces
fragmentation in the chunks when the main page\r\nloads.\r\n\r\n| Before
| After |\r\n|--------|--------|\r\n| <img width=\"525\"
alt=\"Screenshot 2024-10-02 at 09 56
35\"\r\nsrc=\"https://github.com/user-attachments/assets/06fec02c-ff2c-4771-981f-a761bda67eae\">\r\n|
<img width=\"521\" alt=\"Screenshot 2024-10-02 at 09 59
16\"\r\nsrc=\"https://github.com/user-attachments/assets/a243b09a-9d83-4d0d-b875-20855bb18f5d\">\r\n|\r\n|
<img width=\"1398\" alt=\"Screenshot 2024-10-02 at 09 56
55\"\r\nsrc=\"https://github.com/user-attachments/assets/66d2c131-b0b7-47e1-9a9a-e1be57e69bbb\">\r\n|
<img width=\"678\" alt=\"Screenshot 2024-10-02 at 09 58
59\"\r\nsrc=\"https://github.com/user-attachments/assets/39e6515e-5a83-4d97-97c8-cce01b7c6887\">\r\n|\r\n\r\nCo-authored-by:
Marco Antonio Ghiani
<marcoantonio.ghiani@elastic.co>","sha":"ce8c9d8d63ac8d67e975f4cd15cdb665a064d67e","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","backport:prev-minor","ci:project-deploy-observability","Team:obs-ux-logs"],"title":"[Dataset
Quality] Optimize bundle size and chunks
fragmentation","number":194661,"url":"https://github.com/elastic/kibana/pull/194661","mergeCommit":{"message":"[Dataset
Quality] Optimize bundle size and chunks fragmentation (#194661)\n\n## 📓
Summary\r\n\r\nCloses #191602 \r\n\r\nThis work reduces the initial
bundle size for the dataset quality plugin\r\nby **~55%** and reduces
fragmentation in the chunks when the main page\r\nloads.\r\n\r\n| Before
| After |\r\n|--------|--------|\r\n| <img width=\"525\"
alt=\"Screenshot 2024-10-02 at 09 56
35\"\r\nsrc=\"https://github.com/user-attachments/assets/06fec02c-ff2c-4771-981f-a761bda67eae\">\r\n|
<img width=\"521\" alt=\"Screenshot 2024-10-02 at 09 59
16\"\r\nsrc=\"https://github.com/user-attachments/assets/a243b09a-9d83-4d0d-b875-20855bb18f5d\">\r\n|\r\n|
<img width=\"1398\" alt=\"Screenshot 2024-10-02 at 09 56
55\"\r\nsrc=\"https://github.com/user-attachments/assets/66d2c131-b0b7-47e1-9a9a-e1be57e69bbb\">\r\n|
<img width=\"678\" alt=\"Screenshot 2024-10-02 at 09 58
59\"\r\nsrc=\"https://github.com/user-attachments/assets/39e6515e-5a83-4d97-97c8-cce01b7c6887\">\r\n|\r\n\r\nCo-authored-by:
Marco Antonio Ghiani
<marcoantonio.ghiani@elastic.co>","sha":"ce8c9d8d63ac8d67e975f4cd15cdb665a064d67e"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/194661","number":194661,"mergeCommit":{"message":"[Dataset
Quality] Optimize bundle size and chunks fragmentation (#194661)\n\n## 📓
Summary\r\n\r\nCloses #191602 \r\n\r\nThis work reduces the initial
bundle size for the dataset quality plugin\r\nby **~55%** and reduces
fragmentation in the chunks when the main page\r\nloads.\r\n\r\n| Before
| After |\r\n|--------|--------|\r\n| <img width=\"525\"
alt=\"Screenshot 2024-10-02 at 09 56
35\"\r\nsrc=\"https://github.com/user-attachments/assets/06fec02c-ff2c-4771-981f-a761bda67eae\">\r\n|
<img width=\"521\" alt=\"Screenshot 2024-10-02 at 09 59
16\"\r\nsrc=\"https://github.com/user-attachments/assets/a243b09a-9d83-4d0d-b875-20855bb18f5d\">\r\n|\r\n|
<img width=\"1398\" alt=\"Screenshot 2024-10-02 at 09 56
55\"\r\nsrc=\"https://github.com/user-attachments/assets/66d2c131-b0b7-47e1-9a9a-e1be57e69bbb\">\r\n|
<img width=\"678\" alt=\"Screenshot 2024-10-02 at 09 58
59\"\r\nsrc=\"https://github.com/user-attachments/assets/39e6515e-5a83-4d97-97c8-cce01b7c6887\">\r\n|\r\n\r\nCo-authored-by:
Marco Antonio Ghiani
<marcoantonio.ghiani@elastic.co>","sha":"ce8c9d8d63ac8d67e975f4cd15cdb665a064d67e"}}]}]
BACKPORT-->

Co-authored-by: Marco Antonio Ghiani <marcoantonio.ghiani01@gmail.com>
This commit is contained in:
Kibana Machine 2024-10-03 04:23:38 +10:00 committed by GitHub
parent 444b0ca895
commit 0137e864fd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 118 additions and 78 deletions

View file

@ -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;
@ -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}>
@ -72,7 +69,6 @@ function DatasetQuality() {
<EuiFlexItem grow={false}>
<Warnings />
</EuiFlexItem>
<EmptyStateWrapper>
<EuiFlexItem grow={false}>
<Filters />

View file

@ -1,8 +0,0 @@
/*
* 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.
*/
export * from './dataset_quality';

View file

@ -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}
/>
);
};
};

View file

@ -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,
@ -22,11 +22,11 @@ type InitialState = DatasetQualityPublicStateUpdate;
interface Dependencies {
core: CoreStart;
dataStreamStatsClient: IDataStreamsStatsClient;
dataStreamStatsService: DataStreamsStatsServiceStart;
}
export const createDatasetQualityControllerFactory =
({ core, dataStreamStatsClient }: Dependencies) =>
({ core, dataStreamStatsService }: Dependencies) =>
async ({
initialState = DEFAULT_CONTEXT,
}: {
@ -34,6 +34,8 @@ export const createDatasetQualityControllerFactory =
}): Promise<DatasetQualityController> => {
const initialContext = getContextFromPublicState(initialState ?? {});
const dataStreamStatsClient = await dataStreamStatsService.getClient();
const machine = createDatasetQualityControllerStateMachine({
initialContext,
toasts: core.notifications.toasts,

View file

@ -11,8 +11,8 @@ 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';
@ -20,12 +20,12 @@ import { DatasetQualityDetailsController, DatasetQualityDetailsPublicStateUpdate
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,
}: {
@ -33,6 +33,11 @@ export const createDatasetQualityDetailsControllerFactory =
}): Promise<DatasetQualityDetailsController> => {
const initialContext = getContextFromPublicState(initialState);
const [dataStreamStatsClient, dataStreamDetailsClient] = await Promise.all([
dataStreamStatsService.getClient(),
dataStreamDetailsService.getClient(),
]);
const machine = createDatasetQualityDetailsControllerStateMachine({
initialContext,
plugins,

View file

@ -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';

View file

@ -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,
@ -52,7 +52,7 @@ export class DatasetQualityPlugin
const createDatasetQualityController = createDatasetQualityControllerLazyFactory({
core,
dataStreamStatsClient,
dataStreamStatsService,
});
const DatasetQualityDetails = createDatasetQualityDetails({
@ -64,8 +64,8 @@ export class DatasetQualityPlugin
const createDatasetQualityDetailsController = createDatasetQualityDetailsControllerLazyFactory({
core,
plugins,
dataStreamStatsClient,
dataStreamDetailsClient,
dataStreamStatsService,
dataStreamDetailsService,
});
return {

View file

@ -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;
}
}

View file

@ -5,6 +5,5 @@
* 2.0.
*/
export * from './data_stream_details_client';
export * from './data_stream_details_service';
export * from './types';

View file

@ -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 {

View file

@ -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;
}
}

View file

@ -5,6 +5,5 @@
* 2.0.
*/
export * from './data_streams_stats_client';
export * from './data_streams_stats_service';
export * from './types';

View file

@ -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 {