Skip to content

ref(insights): Refactor PerformanceScoreBreakdownChart #89632

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 17, 2025

Conversation

billyvg
Copy link
Member

@billyvg billyvg commented Apr 15, 2025

Move into its own component and parse location query itself

Part of #88560

Move into its own component and parse location query itself

Part of #88560
@github-actions github-actions bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Apr 15, 2025
Comment on lines 22 to 32
const {
transaction,
[SpanIndexedField.BROWSER_NAME]: browserTypes,
[SpanIndexedField.USER_GEO_SUBREGION]: subregions,
} = useLocationQuery({
fields: {
[SpanIndexedField.BROWSER_NAME]: decodeBrowserTypes,
[SpanIndexedField.USER_GEO_SUBREGION]: decodeList,
transaction: decodeList,
},
});
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated this to use useLocationQuery

@billyvg billyvg marked this pull request as ready for review April 15, 2025 19:07
@billyvg billyvg requested a review from a team as a code owner April 15, 2025 19:07
@billyvg billyvg removed the request for review from a team April 15, 2025 19:19
@billyvg billyvg marked this pull request as draft April 15, 2025 19:19
Comment on lines -98 to -99
browserTypes={browserTypes}
subregions={subregions}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the new widget grabs these itself from query params

@@ -33,10 +28,7 @@ export const ORDER: WebVitals[] = ['lcp', 'fcp', 'inp', 'cls', 'ttfb'];
export function PerformanceScoreChart({
projectScore,
webVital,
transaction,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only pageOverview passes transaction, and it comes from query params, so this was moved into the new widget

Comment on lines -38 to -39
browserTypes,
subregions,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto re: query params and moving to new widget

@billyvg billyvg marked this pull request as ready for review April 15, 2025 19:39
@billyvg
Copy link
Member Author

billyvg commented Apr 15, 2025

@codecov-ai-reviewer review

Copy link

codecov-ai bot commented Apr 15, 2025

On it! We are reviewing the PR and will provide feedback shortly.

Comment on lines 19 to 30
import {SpanIndexedField, SpanMetricsField} from 'sentry/views/insights/types';

export function PerformanceScoreBreakdownChartWidget(props: LoadableChartWidgetProps) {
const {
transaction,
[SpanIndexedField.BROWSER_NAME]: browserTypes,
[SpanIndexedField.USER_GEO_SUBREGION]: subregions,
} = useLocationQuery({
fields: {
[SpanIndexedField.BROWSER_NAME]: decodeBrowserTypes,
[SpanIndexedField.USER_GEO_SUBREGION]: decodeList,
transaction: decodeList,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new component could benefit from proper TypeScript interfaces for better type safety and documentation. Consider extracting the type definition for the decoded query parameters into a separate interface. Additionally, the useLocationQuery hook's fields object could be moved to a constant to avoid recreating it on every render.

Suggested change
import {SpanIndexedField, SpanMetricsField} from 'sentry/views/insights/types';
export function PerformanceScoreBreakdownChartWidget(props: LoadableChartWidgetProps) {
const {
transaction,
[SpanIndexedField.BROWSER_NAME]: browserTypes,
[SpanIndexedField.USER_GEO_SUBREGION]: subregions,
} = useLocationQuery({
fields: {
[SpanIndexedField.BROWSER_NAME]: decodeBrowserTypes,
[SpanIndexedField.USER_GEO_SUBREGION]: decodeList,
transaction: decodeList,
interface QueryParams {
[SpanIndexedField.BROWSER_NAME]: ReturnType<typeof decodeBrowserTypes>;
[SpanIndexedField.USER_GEO_SUBREGION]: string[];
transaction: string[];
}
const QUERY_FIELDS = {
[SpanIndexedField.BROWSER_NAME]: decodeBrowserTypes,
[SpanIndexedField.USER_GEO_SUBREGION]: decodeList,
transaction: decodeList,
};
export function PerformanceScoreBreakdownChartWidget(props: LoadableChartWidgetProps) {
const {
transaction,
[SpanIndexedField.BROWSER_NAME]: browserTypes,
[SpanIndexedField.USER_GEO_SUBREGION]: subregions,
} = useLocationQuery<QueryParams>({
fields: QUERY_FIELDS,
});

Comment on lines 80 to 105
const weights = getWeights(webVitalsThatHaveData);

const allSeries: DiscoverSeries[] = vitalScoresData
? ORDER.map((webVital, index) => {
const key = `performance_score(measurements.score.${webVital})` as const;
const series = vitalScoresData[key];

const scaledSeries: DiscoverSeries = {
...series,
data: series.data.map(datum => {
return {
...datum,
value: datum.value * weights[webVital],
};
}),
color: segmentColors[index],
meta: {
// TODO: The backend doesn't return these score fields with the "score" type yet. Fill this in manually for now.
fields: {
...series.meta?.fields,
[key]: 'score',
},
units: series.meta?.units,
},
};

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The series transformation logic is quite complex and could be extracted into a separate utility function for better maintainability and testability. Also consider adding memoization for the allSeries calculation to prevent unnecessary recalculations on re-renders.

Suggested change
const weights = getWeights(webVitalsThatHaveData);
const allSeries: DiscoverSeries[] = vitalScoresData
? ORDER.map((webVital, index) => {
const key = `performance_score(measurements.score.${webVital})` as const;
const series = vitalScoresData[key];
const scaledSeries: DiscoverSeries = {
...series,
data: series.data.map(datum => {
return {
...datum,
value: datum.value * weights[webVital],
};
}),
color: segmentColors[index],
meta: {
// TODO: The backend doesn't return these score fields with the "score" type yet. Fill this in manually for now.
fields: {
...series.meta?.fields,
[key]: 'score',
},
units: series.meta?.units,
},
};
const transformVitalScores = useCallback((vitalScoresData: any, segmentColors: string[], weights: Record<string, number>): DiscoverSeries[] => {
return ORDER.map((webVital, index) => {
const key = `performance_score(measurements.score.${webVital})` as const;
const series = vitalScoresData[key];
return {
...series,
data: series.data.map(datum => ({
...datum,
value: datum.value * weights[webVital],
})),
color: segmentColors[index],
meta: {
fields: {
...series.meta?.fields,
[key]: 'score',
},
units: series.meta?.units,
},
};
});
}, []);
const allSeries = useMemo(
() => (vitalScoresData ? transformVitalScores(vitalScoresData, segmentColors, weights) : []),
[vitalScoresData, segmentColors, weights, transformVitalScores]
);

@billyvg billyvg requested a review from gggritso April 15, 2025 20:06
- remove shallow unneeded chart wrapper
- rename helper-only file to match the function inside
@gggritso gggritso merged commit f79cc85 into master Apr 17, 2025
45 checks passed
@gggritso gggritso deleted the ref-insights-combine-web-vitals-widgets branch April 17, 2025 20:37
andrewshie-sentry pushed a commit that referenced this pull request Apr 22, 2025
Move into its own component and parse location query itself

Part of #88560

---------

Co-authored-by: George Gritsouk <989898+gggritso@users.noreply.github.com>
@github-actions github-actions bot locked and limited conversation to collaborators May 3, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Scope: Frontend Automatically applied to PRs that change frontend components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants