Prevent layout shifts caused by AssetInventory-specific components (#216001)

## Summary

This will reduce the current "jumpy" experience improving the perceived
quality while also boosting performance.

Part of the solution for:
- https://github.com/elastic/security-team/issues/12209

Depends on:

- https://github.com/elastic/kibana/pull/215963
- https://github.com/elastic/kibana/pull/212955
- https://github.com/elastic/kibana/pull/215733

### Motivation

The consequence of layout shifts is browsers need to perform a new
rendering cycle, affecting performance negatively:

- **Layout**. This means they need to calculate again the exact position
and size of every visible element, an expensive operation also known as
"reflow".
- **Paint**. Once the layout is ready, browsers need to fill those
pixels with colors, borders, text, shadow, etc...
- **Composite** (Layering and rendering). Finally, browsers put
everything together in different layers and render them on screen.

### Screenshots Before

<details><summary>TBD</summary>

</details>

### Screenshots After

<details><summary>TBD</summary>

</details>

### Checklist

- [ ] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)
- [ ]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [ ] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [ ] If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)
- [x] This was checked for breaking HTTP API changes, and any breaking
changes have been approved by the breaking-change committee. The
`release_note:breaking` label should be applied in these situations.
- [ ] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
- [x] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

### Identify risks

No risk since feature is not publicly available yet.
This commit is contained in:
Alberto Blázquez 2025-04-01 12:27:02 +02:00 committed by GitHub
parent a987209d3f
commit 931d2d652e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 30 additions and 9 deletions

View file

@ -239,7 +239,7 @@ export const AssetInventoryDataTable = ({
};
}, [persistedSettings]);
const { dataView } = useDataViewContext();
const { dataView, dataViewIsLoading } = useDataViewContext();
const {
uiActions,
@ -369,8 +369,7 @@ export const AssetInventoryDataTable = ({
},
];
const loadingState =
isLoadingGridData || !dataView ? DataLoadingState.loading : DataLoadingState.loaded;
const loadingState = isLoadingGridData ? DataLoadingState.loading : DataLoadingState.loaded;
return (
<CellActionsProvider getTriggerCompatibleActions={uiActions.getTriggerCompatibleActions}>
@ -381,8 +380,13 @@ export const AssetInventoryDataTable = ({
height: computeDataTableRendering.wrapperHeight,
}}
>
<EuiProgress size="xs" color="accent" style={{ opacity: isFetchingGridData ? 1 : 0 }} />
{!dataView ? null : loadingState === DataLoadingState.loaded && totalHits === 0 ? (
<EuiProgress
size="xs"
color="accent"
style={{ opacity: isFetchingGridData ? 1 : 0 }}
className={styles.gridProgressBar}
/>
{dataViewIsLoading ? null : loadingState === DataLoadingState.loaded && totalHits === 0 ? (
<AssetInventoryEmptyState onResetFilters={onResetFilters} />
) : (
<UnifiedDataTable

View file

@ -69,15 +69,20 @@ export const AssetInventoryFilters = ({ setQuery }: AssetInventoryFiltersProps)
[dataView]
);
if (!spaceId || !dataViewSpec) {
if (!spaceId) {
// TODO Add error handling if no spaceId is found
return null;
}
if (dataViewIsLoading) {
return (
<EuiFlexItem grow={true}>
<FilterGroupLoading />
</EuiFlexItem>
<>
<EuiSpacer size="l" />
<EuiFlexItem grow={true}>
<FilterGroupLoading />
</EuiFlexItem>
<EuiSpacer size="l" />
</>
);
}

View file

@ -13,9 +13,20 @@ export const useStyles = () => {
const gridContainer = css`
min-height: 400px;
display: flex;
flex-direction: column;
`;
const gridProgressBar = css`
flex-shrink: 0;
width: 100%;
`;
const gridStyle = css`
& .euiDataGrid__loading {
margin-top: auto;
margin-bottom: auto;
}
& .euiDataGridHeaderCell__icon {
display: none;
}
@ -76,5 +87,6 @@ export const useStyles = () => {
gridStyle,
groupBySelector,
gridContainer,
gridProgressBar,
};
};