From 10742091988f7e2e1075773d7cce540a7937964f Mon Sep 17 00:00:00 2001 From: Catherine Lee <55311782+c298lee@users.noreply.github.com> Date: Fri, 13 Sep 2024 11:42:57 -0400 Subject: [PATCH] feat(replay): Replay web vitals tooltip (#77437) Adds a tooltip beside each web vital type to provide information about what each web vital type is. Also removes FID since Google no longer supports it. Closes https://github.com/getsentry/sentry/issues/77409 --- static/app/utils/replays/getFrameDetails.tsx | 50 ++++++++++++++++++-- static/app/utils/replays/replayReader.tsx | 7 ++- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/static/app/utils/replays/getFrameDetails.tsx b/static/app/utils/replays/getFrameDetails.tsx index 79b5cd12a83e0..4cd54bc56fd93 100644 --- a/static/app/utils/replays/getFrameDetails.tsx +++ b/static/app/utils/replays/getFrameDetails.tsx @@ -1,6 +1,8 @@ -import type {ReactNode} from 'react'; +import {Fragment, type ReactNode} from 'react'; +import styled from '@emotion/styled'; import ExternalLink from 'sentry/components/links/externalLink'; +import QuestionTooltip from 'sentry/components/questionTooltip'; import CrumbErrorTitle from 'sentry/components/replays/breadcrumbs/errorTitle'; import SelectorList from 'sentry/components/replays/breadcrumbs/selectorList'; import { @@ -25,6 +27,7 @@ import { IconWifi, } from 'sentry/icons'; import {t, tct} from 'sentry/locale'; +import {space} from 'sentry/styles/space'; import {explodeSlug} from 'sentry/utils'; import {TabKey} from 'sentry/utils/replays/hooks/useActiveReplayTab'; import type { @@ -52,6 +55,7 @@ import { import {toTitleCase} from 'sentry/utils/string/toTitleCase'; import type {Color} from 'sentry/utils/theme'; import stripURLOrigin from 'sentry/utils/url/stripURLOrigin'; +import {MODULE_DOC_LINK} from 'sentry/views/insights/browser/webVitals/settings'; interface Details { color: Color; @@ -292,7 +296,7 @@ const MAPPER_FOR_FRAME: Record Details> = { unit: isCLSFrame(frame) ? '' : 'ms', }), tabKey: TabKey.NETWORK, - title: 'Web Vital: ' + toTitleCase(explodeSlug(frame.description)), + title: WebVitalTitle(frame), icon: , }; case 'needs-improvement': @@ -303,7 +307,7 @@ const MAPPER_FOR_FRAME: Record Details> = { unit: isCLSFrame(frame) ? '' : 'ms', }), tabKey: TabKey.NETWORK, - title: 'Web Vital: ' + toTitleCase(explodeSlug(frame.description)), + title: WebVitalTitle(frame), icon: , }; default: @@ -314,7 +318,7 @@ const MAPPER_FOR_FRAME: Record Details> = { unit: isCLSFrame(frame) ? '' : 'ms', }), tabKey: TabKey.NETWORK, - title: 'Web Vital: ' + toTitleCase(explodeSlug(frame.description)), + title: WebVitalTitle(frame), icon: , }; } @@ -472,3 +476,41 @@ function stringifyNodeAttributes(node: SlowClickFrame['data']['node']) { : '' }`; } + +function WebVitalTitle(frame: WebVitalFrame) { + const vitalDefinition = function () { + switch (frame.description) { + case 'cumulative-layout-shift': + return 'Cumulative Layout Shift (CLS) is the sum of individual layout shift scores for every unexpected element shift during the rendering process. '; + case 'interaction-to-next-paint': + return "Interaction to Next Paint (INP) is a metric that assesses a page's overall responsiveness to user interactions by observing the latency of all user interactions that occur throughout the lifespan of a user's visit to a page. "; + case 'largest-contentful-paint': + return 'Largest Contentful Paint (LCP) measures the render time for the largest content to appear in the viewport. '; + default: + return ''; + } + }; + return ( + + {t('Web Vital: ') + toTitleCase(explodeSlug(frame.description))} + <QuestionTooltip + isHoverable + size={'xs'} + title={ + <Fragment> + {vitalDefinition()} + <ExternalLink href={`${MODULE_DOC_LINK}/web-vitals-concepts/`}> + {t('Learn more about web vitals here.')} + </ExternalLink> + </Fragment> + } + /> + + ); +} + +const Title = styled('div')` + display: flex; + align-items: center; + gap: ${space(0.5)}; +`; diff --git a/static/app/utils/replays/replayReader.tsx b/static/app/utils/replays/replayReader.tsx index 87c8bd7739a81..16c2bf8bef8f0 100644 --- a/static/app/utils/replays/replayReader.tsx +++ b/static/app/utils/replays/replayReader.tsx @@ -647,7 +647,12 @@ export default class ReplayReader { } } } - return allWebVitals.filter(frame => !groupedCls.includes(frame)).reverse(); + return allWebVitals + .filter( + frame => + !groupedCls.includes(frame) && frame.description !== 'first-input-delay' + ) + .reverse(); } return []; });