useTransactionWebVitalsQuery.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import {useDiscoverQuery} from 'sentry/utils/discover/discoverQuery';
  2. import EventView from 'sentry/utils/discover/eventView';
  3. import {Sort} from 'sentry/utils/discover/fields';
  4. import {DiscoverDatasets} from 'sentry/utils/discover/types';
  5. import {useLocation} from 'sentry/utils/useLocation';
  6. import useOrganization from 'sentry/utils/useOrganization';
  7. import usePageFilters from 'sentry/utils/usePageFilters';
  8. import {calculatePerformanceScore} from 'sentry/views/performance/browser/webVitals/utils/calculatePerformanceScore';
  9. import {mapWebVitalToOrderBy} from 'sentry/views/performance/browser/webVitals/utils/mapWebVitalToOrderBy';
  10. import {
  11. RowWithScore,
  12. WebVitals,
  13. } from 'sentry/views/performance/browser/webVitals/utils/types';
  14. import {useWebVitalsSort} from 'sentry/views/performance/browser/webVitals/utils/useWebVitalsSort';
  15. type Props = {
  16. defaultSort?: Sort;
  17. limit?: number;
  18. orderBy?: WebVitals | null;
  19. sortName?: string;
  20. transaction?: string | null;
  21. };
  22. export const useTransactionWebVitalsQuery = ({
  23. orderBy,
  24. limit,
  25. transaction,
  26. defaultSort,
  27. sortName = 'sort',
  28. }: Props) => {
  29. const organization = useOrganization();
  30. const pageFilters = usePageFilters();
  31. const location = useLocation();
  32. const sort = useWebVitalsSort({sortName, defaultSort});
  33. const eventView = EventView.fromNewQueryWithPageFilters(
  34. {
  35. fields: [
  36. 'transaction',
  37. 'transaction.op',
  38. 'p75(measurements.lcp)',
  39. 'p75(measurements.fcp)',
  40. 'p75(measurements.cls)',
  41. 'p75(measurements.ttfb)',
  42. 'p75(measurements.fid)',
  43. 'count()',
  44. ],
  45. name: 'Web Vitals',
  46. query:
  47. 'transaction.op:pageload' + (transaction ? ` transaction:"${transaction}"` : ''),
  48. orderby: mapWebVitalToOrderBy(orderBy, 'p75') ?? '-count',
  49. version: 2,
  50. dataset: DiscoverDatasets.METRICS,
  51. },
  52. pageFilters.selection
  53. );
  54. eventView.sorts = [sort];
  55. const {data, isLoading, ...rest} = useDiscoverQuery({
  56. eventView,
  57. limit: limit ?? 50,
  58. location,
  59. orgSlug: organization.slug,
  60. options: {
  61. enabled: pageFilters.isReady,
  62. refetchOnWindowFocus: false,
  63. },
  64. });
  65. const tableData: RowWithScore[] =
  66. !isLoading && data?.data.length
  67. ? data.data
  68. .map(row => ({
  69. transaction: row.transaction?.toString(),
  70. 'transaction.op': row['transaction.op']?.toString(),
  71. 'p75(measurements.lcp)': row['p75(measurements.lcp)'] as number,
  72. 'p75(measurements.fcp)': row['p75(measurements.fcp)'] as number,
  73. 'p75(measurements.cls)': row['p75(measurements.cls)'] as number,
  74. 'p75(measurements.ttfb)': row['p75(measurements.ttfb)'] as number,
  75. 'p75(measurements.fid)': row['p75(measurements.fid)'] as number,
  76. 'count()': row['count()'] as number,
  77. }))
  78. .map(row => {
  79. const {totalScore, clsScore, fcpScore, lcpScore, ttfbScore, fidScore} =
  80. calculatePerformanceScore({
  81. lcp: row['p75(measurements.lcp)'],
  82. fcp: row['p75(measurements.fcp)'],
  83. cls: row['p75(measurements.cls)'],
  84. ttfb: row['p75(measurements.ttfb)'],
  85. fid: row['p75(measurements.fid)'],
  86. });
  87. return {
  88. ...row,
  89. score: totalScore,
  90. clsScore,
  91. fcpScore,
  92. lcpScore,
  93. ttfbScore,
  94. fidScore,
  95. };
  96. })
  97. : [];
  98. return {
  99. data: tableData,
  100. isLoading,
  101. ...rest,
  102. };
  103. };