Skip to content

Commit

Permalink
[RUM Dashboard] Replace FID with INP (elastic#172467)
Browse files Browse the repository at this point in the history
  • Loading branch information
shahzad31 authored Dec 5, 2023
1 parent dc88dee commit 9695939
Show file tree
Hide file tree
Showing 38 changed files with 560 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ export async function getServiceTransactionTypes({
params
);
const transactionTypes =
aggregations?.types.buckets.map((bucket) => bucket.key as string) || [];
aggregations?.types.buckets
.map((bucket) => bucket.key as string)
// we exclude page-exit transactions because they are not relevant for the apm app
// and are only used for the INP values
.filter((value) => value !== 'page-exit') || [];
return { transactionTypes };
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { ReportViewType } from '../../types';
import {
CLS_FIELD,
FCP_FIELD,
FID_FIELD,
INP_FIELD,
LCP_FIELD,
TBT_FIELD,
TRANSACTION_DURATION,
Expand All @@ -31,7 +31,7 @@ import {
ENVIRONMENT_LABEL,
EVENT_DATASET_LABEL,
FCP_LABEL,
FID_LABEL,
INP_LABEL,
HEATMAP_LABEL,
HOST_NAME_LABEL,
KPI_LABEL,
Expand Down Expand Up @@ -102,7 +102,7 @@ export const FieldLabels: Record<string, string> = {
[LCP_FIELD]: LCP_LABEL,
[FCP_FIELD]: FCP_LABEL,
[TBT_FIELD]: TBT_LABEL,
[FID_FIELD]: FID_LABEL,
[INP_FIELD]: INP_LABEL,
[CLS_FIELD]: CLS_LABEL,

[SYNTHETICS_CLS]: CLS_LABEL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ export const FCP_FIELD = 'transaction.marks.agent.firstContentfulPaint';
export const LCP_FIELD = 'transaction.marks.agent.largestContentfulPaint';
export const TBT_FIELD = 'transaction.experience.tbt';
export const FID_FIELD = 'transaction.experience.fid';
export const INP_FIELD = 'numeric_labels.inp_value';
export const CLS_FIELD = 'transaction.experience.cls';

export const PROFILE_ID = 'profile.id';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ export const FID_LABEL = i18n.translate('xpack.exploratoryView.expView.fieldLabe
defaultMessage: 'First input delay',
});

export const INP_LABEL = i18n.translate('xpack.exploratoryView.expView.fieldLabels.inp', {
defaultMessage: 'Interaction to next paint',
});

export const CLS_LABEL = i18n.translate('xpack.exploratoryView.expView.fieldLabels.cls', {
defaultMessage: 'Cumulative layout shift',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ import {
ReportTypes,
USE_BREAK_DOWN_COLUMN,
} from '../constants';
import { buildPhraseFilter } from '../utils';
import { buildPhraseFilter, buildPhrasesFilter } from '../utils';
import {
CLIENT_GEO_COUNTRY_NAME,
CLS_FIELD,
FID_FIELD,
INP_FIELD,
LCP_FIELD,
PROCESSOR_EVENT,
SERVICE_NAME,
Expand All @@ -32,8 +32,9 @@ import {
USER_AGENT_OS_VERSION,
URL_FULL,
SERVICE_ENVIRONMENT,
FID_FIELD,
} from '../constants/elasticsearch_fieldnames';
import { CLS_LABEL, FID_LABEL, LCP_LABEL } from '../constants/labels';
import { CLS_LABEL, FID_LABEL, INP_LABEL, LCP_LABEL } from '../constants/labels';

export function getCoreWebVitalsConfig({ dataView }: ConfigProps): SeriesConfig {
const statusPallete = euiPaletteForStatus(3);
Expand Down Expand Up @@ -87,7 +88,7 @@ export function getCoreWebVitalsConfig({ dataView }: ConfigProps): SeriesConfig
URL_FULL,
],
baseFilters: [
...buildPhraseFilter(TRANSACTION_TYPE, 'page-load', dataView),
...buildPhrasesFilter(TRANSACTION_TYPE, ['page-load', 'page-exit'], dataView),
...buildPhraseFilter(PROCESSOR_EVENT, 'transaction', dataView),
],
labels: { ...FieldLabels, [SERVICE_NAME]: 'Web Application' },
Expand All @@ -113,21 +114,21 @@ export function getCoreWebVitalsConfig({ dataView }: ConfigProps): SeriesConfig
],
},
{
label: FID_LABEL,
id: FID_FIELD,
label: INP_LABEL,
id: INP_FIELD,
columnType: FILTER_RECORDS,
columnFilters: [
{
language: 'kuery',
query: `${FID_FIELD} < 100`,
query: `${INP_FIELD} < 200`,
},
{
language: 'kuery',
query: `${FID_FIELD} > 100 and ${FID_FIELD} < 300`,
query: `${INP_FIELD} > 200 and ${INP_FIELD} < 500`,
},
{
language: 'kuery',
query: `${FID_FIELD} > 300`,
query: `${INP_FIELD} > 500`,
},
],
},
Expand All @@ -150,12 +151,31 @@ export function getCoreWebVitalsConfig({ dataView }: ConfigProps): SeriesConfig
},
],
},
{
label: FID_LABEL,
id: FID_FIELD,
columnType: FILTER_RECORDS,
columnFilters: [
{
language: 'kuery',
query: `${FID_FIELD} < 100`,
},
{
language: 'kuery',
query: `${FID_FIELD} > 100 and ${FID_FIELD} < 300`,
},
{
language: 'kuery',
query: `${FID_FIELD} > 300`,
},
],
},
],
yConfig: [
{ color: statusPallete[0], forAccessor: 'y-axis-column' },
{ color: statusPallete[1], forAccessor: 'y-axis-column-1' },
{ color: statusPallete[2], forAccessor: 'y-axis-column-2' },
],
query: { query: 'transaction.type: "page-load"', language: 'kuery' },
query: { query: 'transaction.type: ("page-load" or "page-exit")', language: 'kuery' },
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
CLIENT_GEO_COUNTRY_NAME,
CLS_FIELD,
FCP_FIELD,
FID_FIELD,
INP_FIELD,
LCP_FIELD,
PROCESSOR_EVENT,
SERVICE_ENVIRONMENT,
Expand All @@ -37,7 +37,7 @@ import {
BACKEND_TIME_LABEL,
CLS_LABEL,
FCP_LABEL,
FID_LABEL,
INP_LABEL,
LCP_LABEL,
PAGE_LOAD_TIME_LABEL,
PAGES_LOADED_LABEL,
Expand Down Expand Up @@ -97,7 +97,7 @@ export function getRumDistributionConfig({ dataView }: ConfigProps): SeriesConfi
{ label: FCP_LABEL, id: FCP_FIELD, field: FCP_FIELD },
{ label: TBT_LABEL, id: TBT_FIELD, field: TBT_FIELD },
{ label: LCP_LABEL, id: LCP_FIELD, field: LCP_FIELD },
{ label: FID_LABEL, id: FID_FIELD, field: FID_FIELD },
{ label: INP_LABEL, id: INP_FIELD, field: INP_FIELD },
{ label: CLS_LABEL, id: CLS_FIELD, field: CLS_FIELD },
],
baseFilters: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ export const rumFieldFormats: FieldFormat[] = [
},
},
},
{
field: FID_FIELD,
format: {
id: 'duration',
params: {
inputFormat: 'milliseconds',
outputFormat: 'humanizePrecise',
showSuffix: true,
useShortSuffix: true,
},
},
},
{
field: TRANSACTION_TIME_TO_FIRST_BYTE,
format: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export const sampleAttributeCoreWebVital = {
filter: {
language: 'kuery',
query:
'transaction.type: page-load and processor.event: transaction and transaction.marks.agent.largestContentfulPaint < 2500',
'transaction.type: (page-load or page-exit) and processor.event: transaction and transaction.marks.agent.largestContentfulPaint < 2500',
},
isBucketed: false,
label: 'Good',
Expand All @@ -104,7 +104,7 @@ export const sampleAttributeCoreWebVital = {
query: {
language: 'kuery',
query:
'transaction.type: page-load and processor.event: transaction and transaction.type: "page-load"',
'transaction.type: (page-load or page-exit) and processor.event: transaction and transaction.type: ("page-load" or "page-exit")',
},
visualization: {
axisTitlesVisibilitySettings: {
Expand Down
1 change: 0 additions & 1 deletion x-pack/plugins/observability/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ export {

export type { SloEditLocatorParams } from './locators/slo_edit';

export type { UXMetrics } from './pages/overview/components/sections/ux/core_web_vitals/core_vitals';
export { getCoreVitalsComponent } from './pages/overview/components/sections/ux/core_web_vitals/get_core_web_vitals_lazy';

export { DatePicker } from './pages/overview/components/date_picker/date_picker';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ interface Props {
thresholds: Thresholds;
isCls?: boolean;
helpLabel: string;
dataTestSubj?: string;
}

export function getCoreVitalTooltipMessage(
Expand Down Expand Up @@ -82,6 +83,7 @@ export function CoreVitalItem({
ranks = [100, 0, 0],
isCls,
helpLabel,
dataTestSubj,
}: Props) {
const palette = euiPaletteForStatus(3);

Expand All @@ -96,6 +98,7 @@ export function CoreVitalItem({
return (
<>
<EuiStat
data-test-subj={dataTestSubj}
aria-label={`${title} ${value}`} // aria-label is required when passing a component, instead of a string, as the description
titleSize="s"
title={value ?? ''}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@

import * as React from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
import type { UXMetrics } from '@kbn/observability-shared-plugin/public';
import {
CLS_HELP_LABEL,
CLS_LABEL,
FID_HELP_LABEL,
FID_LABEL,
INP_HELP_LABEL,
INP_LABEL,
LCP_HELP_LABEL,
LCP_LABEL,
} from './translations';
Expand All @@ -28,18 +29,6 @@ export interface CoreVitalProps {
displayTrafficMetric?: boolean;
}

export interface UXMetrics {
cls: number | null;
fid?: number | null;
lcp?: number | null;
tbt: number;
fcp?: number | null;
coreVitalPages: number;
lcpRanks: number[];
fidRanks: number[];
clsRanks: number[];
}

function formatToSec(value?: number | string, fromUnit = 'MicroSec'): string {
const valueInMs = Number(value ?? 0) / (fromUnit === 'MicroSec' ? 1000 : 1);

Expand All @@ -58,7 +47,7 @@ function formatToMilliseconds(value?: number | null) {

const CoreVitalsThresholds = {
LCP: { good: '2.5s', bad: '4.0s' },
FID: { good: '100ms', bad: '300ms' },
INP: { good: '200ms', bad: '500ms' },
CLS: { good: '0.1', bad: '0.25' },
};

Expand All @@ -71,7 +60,7 @@ export default function CoreVitals({
totalPageViews,
displayTrafficMetric = false,
}: CoreVitalProps) {
const { lcp, lcpRanks, fid, fidRanks, cls, clsRanks, coreVitalPages } = data || {};
const { lcp, lcpRanks, inp, inpRanks, cls, clsRanks, coreVitalPages } = data || {};

return (
<>
Expand All @@ -93,16 +82,18 @@ export default function CoreVitals({
loading={loading}
thresholds={CoreVitalsThresholds.LCP}
helpLabel={LCP_HELP_LABEL}
dataTestSubj={'lcp-core-vital'}
/>
</EuiFlexItem>
<EuiFlexItem style={{ flexBasis: 380 }}>
<CoreVitalItem
title={FID_LABEL}
value={formatToMilliseconds(fid)}
ranks={fidRanks}
title={INP_LABEL}
value={formatToMilliseconds(inp)}
ranks={inpRanks}
loading={loading}
thresholds={CoreVitalsThresholds.FID}
helpLabel={FID_HELP_LABEL}
thresholds={CoreVitalsThresholds.INP}
helpLabel={INP_HELP_LABEL}
dataTestSubj={'inp-core-vital'}
/>
</EuiFlexItem>
<EuiFlexItem style={{ flexBasis: 380 }}>
Expand All @@ -114,6 +105,7 @@ export default function CoreVitals({
thresholds={CoreVitalsThresholds.CLS}
isCls={true}
helpLabel={CLS_HELP_LABEL}
dataTestSubj={'cls-core-vital'}
/>
</EuiFlexItem>
</EuiFlexGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export const LCP_LABEL = i18n.translate('xpack.observability.ux.coreVitals.lcp',
defaultMessage: 'Largest contentful paint',
});

export const FID_LABEL = i18n.translate('xpack.observability.ux.coreVitals.fip', {
defaultMessage: 'First input delay',
export const INP_LABEL = i18n.translate('xpack.observability.ux.coreVitals.inp', {
defaultMessage: 'Interaction to Next Paint',
});

export const CLS_LABEL = i18n.translate('xpack.observability.ux.coreVitals.cls', {
Expand Down Expand Up @@ -71,9 +71,9 @@ export const LCP_HELP_LABEL = i18n.translate('xpack.observability.ux.coreVitals.
'Largest contentful paint measures loading performance. To provide a good user experience, LCP should occur within 2.5 seconds of when the page first starts loading.',
});

export const FID_HELP_LABEL = i18n.translate('xpack.observability.ux.coreVitals.fid.help', {
export const INP_HELP_LABEL = i18n.translate('xpack.observability.ux.coreVitals.inp.help', {
defaultMessage:
'First input delay measures interactivity. To provide a good user experience, pages should have a FID of less than 100 milliseconds.',
'INP assesses responsiveness using data from the Event Timing API. When an interaction causes a page to become unresponsive, that is a poor user experience. INP observes the latency of all interactions a user has made with the page, and reports a single value which all (or nearly all) interactions were below. A low INP means the page was consistently able to respond quickly to all—or the vast majority—of user interactions.',
});

export const CLS_HELP_LABEL = i18n.translate('xpack.observability.ux.coreVitals.cls.help', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ export const response: UxFetchDataResponse = {
appLink: '/app/ux',
coreWebVitals: {
cls: 0.01,
fid: 13.5,
lcp: 1942.6666666666667,
tbt: 281.55833333333334,
fcp: 1487,
inp: 285,
coreVitalPages: 100,
lcpRanks: [65, 19, 16],
fidRanks: [73, 11, 16],
inpRanks: [73, 11, 16],
clsRanks: [86, 8, 6],
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ describe('UXSection', () => {
expect(getByText('elastic-co-frontend')).toBeInTheDocument();
expect(getByText('Largest contentful paint')).toBeInTheDocument();
expect(getByText('1.94 s')).toBeInTheDocument();
expect(getByText('14 ms')).toBeInTheDocument();
expect(getByText('285 ms')).toBeInTheDocument();
expect(getByText('0.010')).toBeInTheDocument();

// LCP Rank Values
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
* 2.0.
*/

import { UXMetrics } from '@kbn/observability-shared-plugin/public';
import type { ObservabilityApp } from '../../../typings/common';
import type { UXMetrics } from '../../pages/overview/components/sections/ux/core_web_vitals/core_vitals';
import { ApmIndicesConfig } from '../../../common/typings';

export interface Stat {
Expand Down
Loading

0 comments on commit 9695939

Please sign in to comment.