From 7afded1e874d63694edc078a882c7f3f8612dea2 Mon Sep 17 00:00:00 2001 From: ricoberger Date: Fri, 17 Sep 2021 22:23:16 +0200 Subject: [PATCH] Improve performance for large dashboards We are now using Intersection Observer API for dashboards to improve the performance of large dashboards with a lot of panels. The panels are now only rendered when the become visible in the viewport. This improves the perfromance for large dashboards, because we render less DOM elements at the same time. When an Application in the gallery view is selected we are now going directly to the corresponding Application page and do not show the Application in a panel. The panel view is still used for the applications which are selected in the topology view. --- CHANGELOG.md | 1 + .../components/panel/ApplicationsGallery.tsx | 4 +- .../panel/ApplicationsGalleryItem.tsx | 76 +++++++------------ .../src/components/panel/Panel.tsx | 1 - plugins/dashboards/package.json | 1 + .../src/components/dashboards/Dashboard.tsx | 51 ++++++++----- yarn.lock | 5 ++ 7 files changed, 69 insertions(+), 70 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f253c4ce..2672c8562 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,7 @@ NOTE: As semantic versioning states all 0.y.z releases can contain breaking chan - [#147](https://github.com/kobsio/kobs/pull/147): Improve query performance for ClickHouse plugin and allow custom values for the maximum amount of documents, which should be returned (see [#133](https://github.com/kobsio/kobs/pull/133)). - [#148](https://github.com/kobsio/kobs/pull/148): Improve reliability of kobs, by do not checking the database connection for a configured ClickHouse instance. - [#150](https://github.com/kobsio/kobs/pull/150): :warning: *Breaking change:* :warning: The ClickHouse plugin can now only be used together with the [kobsio/fluent-bit-clickhouse](https://github.com/kobsio/fluent-bit-clickhouse) output plugin for [Fluent Bit](https://fluentbit.io). For raw SQL queries against a ClickHouse instance the SQL plugin added in [#149](https://github.com/kobsio/kobs/pull/149) can be used. +- [#152](https://github.com/kobsio/kobs/pull/152): Improve performance for large dashboards and open Application page in gallery view. ## [v0.5.0](https://github.com/kobsio/kobs/releases/tag/v0.5.0) (2021-08-03) diff --git a/plugins/applications/src/components/panel/ApplicationsGallery.tsx b/plugins/applications/src/components/panel/ApplicationsGallery.tsx index b0e89a510..0c1c36f1b 100644 --- a/plugins/applications/src/components/panel/ApplicationsGallery.tsx +++ b/plugins/applications/src/components/panel/ApplicationsGallery.tsx @@ -11,7 +11,6 @@ interface IApplicationsGalleryProps { clusters: string[]; namespaces: string[]; team?: IReference; - showDetails?: (details: React.ReactNode) => void; } // ApplicationsGallery is the component to display all applications inside a gallery view. @@ -19,7 +18,6 @@ const ApplicationsGallery: React.FunctionComponent = clusters, namespaces, team, - showDetails, }: IApplicationsGalleryProps) => { const times: IPluginTimes = { time: 'last15Minutes', @@ -99,7 +97,7 @@ const ApplicationsGallery: React.FunctionComponent = {data.map((application, index) => ( - + ))} diff --git a/plugins/applications/src/components/panel/ApplicationsGalleryItem.tsx b/plugins/applications/src/components/panel/ApplicationsGalleryItem.tsx index 721c7bfab..9410c5e3d 100644 --- a/plugins/applications/src/components/panel/ApplicationsGalleryItem.tsx +++ b/plugins/applications/src/components/panel/ApplicationsGalleryItem.tsx @@ -2,13 +2,11 @@ import { Card, CardBody, CardTitle } from '@patternfly/react-core'; import React from 'react'; import { IPluginTimes, LinkWrapper, PluginPreview } from '@kobsio/plugin-core'; -import Details from './details/Details'; import { IApplication } from '../../utils/interfaces'; interface IApplicationsGalleryItemProps { times: IPluginTimes; application: IApplication; - showDetails?: (details: React.ReactNode) => void; } // ApplicationsGalleryItem renders a single application in a Card component. With the title of the application and the @@ -17,55 +15,35 @@ interface IApplicationsGalleryItemProps { const ApplicationsGalleryItem: React.FunctionComponent = ({ times, application, - showDetails, }: IApplicationsGalleryItemProps) => { - const cardBody = ( - - {application.preview ? ( -
- -
- ) : application.description ? ( -
{application.description}
- ) : ( -
- `${application.namespace} (${application.cluster})` -
- )} -
- ); - - // If the component is used withour a selectApplication function we wrap the card inside our LinkWrapper component, so - // that the user is redirected to the application page, when he selects the card. This is done, so that we can use the - // same component for the applications gallery view, where the application should be shown in the drawer and the teams - // view, where the user should be redirected to the applications page. - if (!showDetails) { - return ( - - - {application.name} - {cardBody} - - - ); - } - return ( - - showDetails(
showDetails(undefined)} />) - } - > - {application.name} - {cardBody} - + + + + {application.name} +
+ + {application.namespace} ({application.cluster}) + +
+ + {application.preview ? ( +
+ +
+ ) : application.description ? ( +
{application.description}
+ ) : ( +
+ )} +
+
+
); }; diff --git a/plugins/applications/src/components/panel/Panel.tsx b/plugins/applications/src/components/panel/Panel.tsx index 00eeb873f..3904eb118 100644 --- a/plugins/applications/src/components/panel/Panel.tsx +++ b/plugins/applications/src/components/panel/Panel.tsx @@ -75,7 +75,6 @@ export const Panel: React.FunctionComponent = ({ clusters={options.clusters || [defaults.cluster]} namespaces={options.namespaces || [defaults.namespace]} team={options.team} - showDetails={showDetails} /> ); diff --git a/plugins/dashboards/package.json b/plugins/dashboards/package.json index 04246f819..0b49a06fe 100644 --- a/plugins/dashboards/package.json +++ b/plugins/dashboards/package.json @@ -17,6 +17,7 @@ "@types/react-router-dom": "^5.1.7", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-intersection-observer": "^8.32.1", "react-query": "^3.17.2", "react-router-dom": "^5.2.0", "typescript": "^4.3.4" diff --git a/plugins/dashboards/src/components/dashboards/Dashboard.tsx b/plugins/dashboards/src/components/dashboards/Dashboard.tsx index 581bc6d4c..ead1d406a 100644 --- a/plugins/dashboards/src/components/dashboards/Dashboard.tsx +++ b/plugins/dashboards/src/components/dashboards/Dashboard.tsx @@ -1,6 +1,7 @@ import { Alert, AlertActionLink, AlertVariant, Grid, GridItem, Spinner, Title } from '@patternfly/react-core'; import { QueryObserverResult, useQuery } from 'react-query'; import React, { memo, useContext, useState } from 'react'; +import { InView } from 'react-intersection-observer'; import { ClustersContext, @@ -197,23 +198,39 @@ const Dashboard: React.FunctionComponent = ({ span={toGridSpans(12, forceDefaultSpan, panel.colSpan)} rowSpan={toGridSpans(1, forceDefaultSpan, panel.rowSpan)} > -
- -
+ + {({ inView, ref }): React.ReactNode => ( +
+ {inView ? ( +
+ +
+ ) : ( +
+ )} +
+ )} +
))} diff --git a/yarn.lock b/yarn.lock index 13ed585e7..5a25da9f2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12434,6 +12434,11 @@ react-error-overlay@^6.0.9: resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a" integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew== +react-intersection-observer@^8.32.1: + version "8.32.1" + resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-8.32.1.tgz#9b949871eb35eb1fc730732bbf8fcfaaaf3f5b02" + integrity sha512-FOmMkMw7MeJ8FkuADpU8TRcvGuTvPB+DRkaikS1QXcWArYLCWC3mjRorq2XeRGBuqmaueOBd27PUazTu9AgInw== + react-is@^16.3.2, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"