[Observability] Lazy load shared components (#88802)

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Shahzad 2021-01-25 17:08:31 +01:00 committed by GitHub
parent e251ff4be5
commit 6391ef9c45
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 78 additions and 33 deletions

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import React, { useContext } from 'react';
import React, { useContext, useMemo } from 'react';
import {
EuiFlexGroup,
EuiFlexItem,
@ -17,7 +17,7 @@ import { I18LABELS } from '../translations';
import { KeyUXMetrics } from './KeyUXMetrics';
import { useFetcher } from '../../../../hooks/use_fetcher';
import { useUxQuery } from '../hooks/useUxQuery';
import { CoreVitals } from '../../../../../../observability/public';
import { getCoreVitalsComponent } from '../../../../../../observability/public';
import { CsmSharedContext } from '../CsmSharedContext';
import { useUrlParams } from '../../../../context/url_params_context/use_url_params';
import { getPercentileLabel } from './translations';
@ -48,6 +48,18 @@ export function UXMetrics() {
sharedData: { totalPageViews },
} = useContext(CsmSharedContext);
const CoreVitals = useMemo(
() =>
getCoreVitalsComponent({
data,
totalPageViews,
loading: status !== 'success',
displayTrafficMetric: true,
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[status]
);
return (
<EuiPanel>
<EuiFlexGroup justifyContent="spaceBetween" wrap>
@ -67,12 +79,7 @@ export function UXMetrics() {
<EuiFlexGroup justifyContent="spaceBetween" wrap>
<EuiFlexItem grow={1} data-cy={`client-metrics`}>
<EuiSpacer size="s" />
<CoreVitals
data={data}
totalPageViews={totalPageViews}
loading={status !== 'success'}
displayTrafficMetric={true}
/>
{CoreVitals}
</EuiFlexItem>
</EuiFlexGroup>
</EuiPanel>

View file

@ -17,7 +17,7 @@ import { i18n } from '@kbn/i18n';
import React, { ReactNode } from 'react';
import styled from 'styled-components';
import { usePluginContext } from '../../../hooks/use_plugin_context';
import { HeaderMenuPortal } from '../../shared/header_menu_portal';
import HeaderMenuPortal from '../../shared/header_menu_portal';
const Container = styled.div<{ color: string }>`
background: ${(props) => props.color};

View file

@ -12,7 +12,7 @@ import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher';
import { useHasData } from '../../../../hooks/use_has_data';
import { useTimeRange } from '../../../../hooks/use_time_range';
import { UXHasDataResponse } from '../../../../typings';
import { CoreVitals } from '../../../shared/core_web_vitals';
import CoreVitals from '../../../shared/core_web_vitals';
interface Props {
bucketSize: string;

View file

@ -16,6 +16,7 @@ import {
import { CoreVitalItem } from './core_vital_item';
import { WebCoreVitalsTitle } from './web_core_vitals_title';
import { ServiceName } from './service_name';
import { CoreVitalProps } from '../types';
export interface UXMetrics {
cls: number | null;
@ -29,7 +30,7 @@ export interface UXMetrics {
clsRanks: number[];
}
export function formatToSec(value?: number | string, fromUnit = 'MicroSec'): string {
function formatToSec(value?: number | string, fromUnit = 'MicroSec'): string {
const valueInMs = Number(value ?? 0) / (fromUnit === 'MicroSec' ? 1000 : 1);
if (valueInMs < 1000) {
@ -51,23 +52,15 @@ const CoreVitalsThresholds = {
CLS: { good: '0.1', bad: '0.25' },
};
interface Props {
loading: boolean;
data?: UXMetrics | null;
displayServiceName?: boolean;
serviceName?: string;
totalPageViews?: number;
displayTrafficMetric?: boolean;
}
export function CoreVitals({
// eslint-disable-next-line import/no-default-export
export default function CoreVitals({
data,
loading,
displayServiceName,
serviceName,
totalPageViews,
displayTrafficMetric = false,
}: Props) {
}: CoreVitalProps) {
const { lcp, lcpRanks, fid, fidRanks, cls, clsRanks, coreVitalPages } = data || {};
return (

View file

@ -4,17 +4,13 @@
* you may not use this file except in compliance with the Elastic License.
*/
import React, { ReactNode, useEffect, useMemo } from 'react';
import React, { useEffect, useMemo } from 'react';
import { createPortalNode, InPortal, OutPortal } from 'react-reverse-portal';
import { AppMountParameters } from '../../../../../../src/core/public';
import { toMountPoint } from '../../../../../../src/plugins/kibana_react/public';
import { HeaderMenuPortalProps } from './types';
interface HeaderMenuPortalProps {
children: ReactNode;
setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'];
}
export function HeaderMenuPortal({ children, setHeaderActionMenu }: HeaderMenuPortalProps) {
// eslint-disable-next-line import/no-default-export
export default function HeaderMenuPortal({ children, setHeaderActionMenu }: HeaderMenuPortalProps) {
const portalNode = useMemo(() => createPortalNode(), []);
useEffect(() => {

View file

@ -0,0 +1,26 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import React, { lazy, Suspense } from 'react';
import { CoreVitalProps, HeaderMenuPortalProps } from './types';
export function getCoreVitalsComponent(props: CoreVitalProps) {
const CoreVitalsLazy = lazy(() => import('./core_web_vitals/index'));
return (
<Suspense fallback={null}>
<CoreVitalsLazy {...props} />
</Suspense>
);
}
export function HeaderMenuPortal(props: HeaderMenuPortalProps) {
const HeaderMenuPortalLazy = lazy(() => import('./header_menu_portal'));
return (
<Suspense fallback={null}>
<HeaderMenuPortalLazy {...props} />
</Suspense>
);
}

View file

@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { ReactNode } from 'react';
import { AppMountParameters } from '../../../../../../src/core/public';
import { UXMetrics } from './core_web_vitals';
export interface HeaderMenuPortalProps {
children: ReactNode;
setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'];
}
export interface CoreVitalProps {
loading: boolean;
data?: UXMetrics | null;
displayServiceName?: boolean;
serviceName?: string;
totalPageViews?: number;
displayTrafficMetric?: boolean;
}

View file

@ -6,8 +6,7 @@
import { PluginInitializerContext, PluginInitializer } from 'kibana/public';
import { Plugin, ObservabilityPluginSetup, ObservabilityPluginStart } from './plugin';
export { HeaderMenuPortal } from './components/shared/header_menu_portal';
export { ObservabilityPluginSetup, ObservabilityPluginStart };
export type { ObservabilityPluginSetup, ObservabilityPluginStart };
export const plugin: PluginInitializer<ObservabilityPluginSetup, ObservabilityPluginStart> = (
context: PluginInitializerContext
@ -17,7 +16,8 @@ export const plugin: PluginInitializer<ObservabilityPluginSetup, ObservabilityPl
export * from './components/shared/action_menu/';
export { UXMetrics, CoreVitals, formatToSec } from './components/shared/core_web_vitals/';
export type { UXMetrics } from './components/shared/core_web_vitals/';
export { getCoreVitalsComponent, HeaderMenuPortal } from './components/shared/';
export {
useTrackPageview,