Skip to content

Commit

Permalink
[Infra UI] Chart load optimization (elastic#162328)
Browse files Browse the repository at this point in the history
Closes elastic#161445

## Summary

This PR enhances the usage of the intersection observer to control the
loading behavior of charts, improving the performance, especially
noticeable during scrolling.


Before 


https://github.com/elastic/kibana/assets/2767137/dfb1d7db-4ddb-41c3-b8ae-3b5bdf3fe36e



After


https://github.com/elastic/kibana/assets/2767137/f348b0b9-4e6f-4163-9eb4-99daea91bbef


Besides, the intersection observer threshold has been set to 0, allowing
charts to start loading as soon as they begin to enter the viewport.


### How to test

- Start a local Kibana instance
- Navigate to `Infrastructure > Hosts`
- Scroll down and confirm that it's not laggy (same for the flyout)

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
crespocarlos and kibanamachine committed Jul 31, 2023
1 parent 0cc81d7 commit 0367514
Show file tree
Hide file tree
Showing 20 changed files with 231 additions and 268 deletions.

This file was deleted.

This file was deleted.

Expand Up @@ -45,7 +45,7 @@ export class XYDataLayer implements ChartLayer<XYDataLayerConfig> {
return this.column[0].getFormulaConfig().label;
}

getBaseColumnColumn(dataView: DataView, options?: XYLayerOptions) {
getBaseLayer(dataView: DataView, options?: XYLayerOptions) {
return {
...getHistogramColumn({
columnName: HISTOGRAM_COLUMN_NAME,
Expand Down Expand Up @@ -75,7 +75,7 @@ export class XYDataLayer implements ChartLayer<XYDataLayerConfig> {
const baseLayer: PersistedIndexPatternLayer = {
columnOrder: [BREAKDOWN_COLUMN_NAME, HISTOGRAM_COLUMN_NAME],
columns: {
...this.getBaseColumnColumn(dataView, this.layerConfig.options),
...this.getBaseLayer(dataView, this.layerConfig.options),
},
};

Expand Down
Expand Up @@ -12,12 +12,7 @@ import { KPI_CHARTS } from '../../../../../common/visualizations/lens/dashboards
export const KPIGrid = React.memo(({ nodeName, dataView, timeRange: dateRange }: TileProps) => {
return (
<>
<EuiFlexGroup
direction="row"
gutterSize="s"
style={{ flexGrow: 0 }}
data-test-subj="assetDetailsKPIGrid"
>
<EuiFlexGroup direction="row" gutterSize="s" data-test-subj="assetDetailsKPIGrid">
{KPI_CHARTS.map((chartProp, index) => (
<EuiFlexItem key={index}>
<Tile {...chartProp} nodeName={nodeName} dataView={dataView} timeRange={dateRange} />
Expand Down
Expand Up @@ -12,11 +12,10 @@ import styled from 'styled-components';
import type { Action } from '@kbn/ui-actions-plugin/public';
import { TimeRange } from '@kbn/es-query';
import { FormattedMessage } from '@kbn/i18n-react';
import { LensWrapper, TooltipContent } from '../../../../lens';
import type { KPIChartProps } from '../../../../../common/visualizations/lens/dashboards/host/kpi_grid_config';
import { useLensAttributes } from '../../../../../hooks/use_lens_attributes';
import { LensWrapper } from '../../../../../common/visualizations/lens/lens_wrapper';
import { buildCombinedHostsFilter } from '../../../../../utils/filters/build';
import { TooltipContent } from '../../../../../common/visualizations/metric_explanation/tooltip_content';

const MIN_HEIGHT = 150;

Expand Down Expand Up @@ -72,7 +71,6 @@ export const Tile = ({
<EuiPanelStyled
hasShadow={false}
paddingSize={error ? 'm' : 'none'}
style={{ minHeight: MIN_HEIGHT }}
data-test-subj={`assetDetailsKPI-${id}`}
>
{error ? (
Expand Down Expand Up @@ -109,6 +107,7 @@ export const Tile = ({
dateRange={timeRange}
filters={filters}
loading={loading}
hidePanelTitles
/>
</EuiToolTip>
)}
Expand All @@ -117,6 +116,7 @@ export const Tile = ({
};

const EuiPanelStyled = styled(EuiPanel)`
min-height: ${MIN_HEIGHT}px;
.echMetric {
border-radius: ${({ theme }) => theme.eui.euiBorderRadius};
pointer-events: none;
Expand Down
Expand Up @@ -12,8 +12,8 @@ import { TypedLensByValueInput } from '@kbn/lens-plugin/public';
import type { DataView } from '@kbn/data-views-plugin/public';
import type { TimeRange } from '@kbn/es-query';
import { FormattedMessage } from '@kbn/i18n-react';
import { LensWrapper } from '../../../../lens/lens_wrapper';
import { buildCombinedHostsFilter } from '../../../../../utils/filters/build';
import { LensWrapper } from '../../../../../common/visualizations/lens/lens_wrapper';
import { useLensAttributes, type Layer } from '../../../../../hooks/use_lens_attributes';
import type { FormulaConfig, XYLayerOptions } from '../../../../../common/visualizations';

Expand Down Expand Up @@ -109,7 +109,6 @@ export const MetricChart = ({
overrides={overrides}
loading={loading}
disableTriggers
hasTitle
/>
)}
</EuiPanel>
Expand Down
Expand Up @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n';
import type { DataView } from '@kbn/data-views-plugin/public';
import { TimeRange } from '@kbn/es-query';
import { FormattedMessage } from '@kbn/i18n-react';
import { HostMetricsDocsLink } from '../../../../../common/visualizations/metric_explanation/host_metrics_docs_link';
import { HostMetricsDocsLink } from '../../../../lens';
import { MetricChart, type MetricChartProps } from './metric_chart';
import { hostLensFormulas } from '../../../../../common/visualizations';

Expand Down
39 changes: 39 additions & 0 deletions x-pack/plugins/infra/public/components/lens/chart_placeholder.tsx
@@ -0,0 +1,39 @@
/*
* 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 { EuiFlexGroup, EuiProgress, EuiFlexItem, EuiLoadingChart } from '@elastic/eui';
import { useEuiTheme } from '@elastic/eui';
import { css } from '@emotion/react';

export const ChartLoadingProgress = ({ hasTopMargin = false }: { hasTopMargin?: boolean }) => {
const { euiTheme } = useEuiTheme();
return (
<EuiProgress
size="xs"
color="accent"
position="absolute"
css={css`
top: ${hasTopMargin ? euiTheme.size.l : 0};
z-index: ${Number(euiTheme.levels.header) - 1};
`}
/>
);
};

export const ChartPlaceholder = ({ style }: { style?: React.CSSProperties }) => {
return (
<>
<ChartLoadingProgress hasTopMargin={false} />
<EuiFlexGroup style={style} justifyContent="center" alignItems="center" responsive={false}>
<EuiFlexItem grow={false}>
<EuiLoadingChart mono size="l" />
</EuiFlexItem>
</EuiFlexGroup>
</>
);
};
12 changes: 12 additions & 0 deletions x-pack/plugins/infra/public/components/lens/index.tsx
@@ -0,0 +1,12 @@
/*
* 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 { ChartPlaceholder } from './chart_placeholder';
export { LensWrapper } from './lens_wrapper';

export { TooltipContent } from './metric_explanation/tooltip_content';
export { HostMetricsDocsLink } from './metric_explanation/host_metrics_docs_link';

0 comments on commit 0367514

Please sign in to comment.