diff --git a/package-lock.json b/package-lock.json
index da3cab252..409111358 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -35,6 +35,7 @@
"react-dom": "^18.2.0",
"react-redux": "^8.0.2",
"react-router-dom": "^6.18.0",
+ "react-virtuoso": "^4.9.0",
"redux": "^4.2.0",
"run": "^1.4.0",
"stream-browserify": "^3.0.0",
@@ -61,6 +62,7 @@
"@types/jest-axe": "^3.5.4",
"@types/material-ui": "^0.21.12",
"@types/node": "^18.6.1",
+ "@types/react-window": "^1.8.8",
"@typescript-eslint/eslint-plugin": "^5.31.0",
"@typescript-eslint/parser": "^5.31.0",
"babel-loader": "^8.2.5",
@@ -4965,6 +4967,15 @@
"@types/react": "*"
}
},
+ "node_modules/@types/react-window": {
+ "version": "1.8.8",
+ "resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.8.tgz",
+ "integrity": "sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==",
+ "dev": true,
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
"node_modules/@types/retry": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
@@ -15202,6 +15213,18 @@
"react-dom": ">=16.6.0"
}
},
+ "node_modules/react-virtuoso": {
+ "version": "4.9.0",
+ "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.9.0.tgz",
+ "integrity": "sha512-MiiSGKqvYPfAK3FUe852n2L3M5IXMKP0pUgYQ/UTk90A/l2UNQOvaEUvAZp+0ytL0kOCNk8i8/J8FMKvIq7kqg==",
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "react": ">=16 || >=17 || >= 18",
+ "react-dom": ">=16 || >=17 || >= 18"
+ }
+ },
"node_modules/read-pkg": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-8.1.0.tgz",
@@ -21550,6 +21573,15 @@
"@types/react": "*"
}
},
+ "@types/react-window": {
+ "version": "1.8.8",
+ "resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.8.tgz",
+ "integrity": "sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==",
+ "dev": true,
+ "requires": {
+ "@types/react": "*"
+ }
+ },
"@types/retry": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
@@ -29062,6 +29094,12 @@
"prop-types": "^15.6.2"
}
},
+ "react-virtuoso": {
+ "version": "4.9.0",
+ "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.9.0.tgz",
+ "integrity": "sha512-MiiSGKqvYPfAK3FUe852n2L3M5IXMKP0pUgYQ/UTk90A/l2UNQOvaEUvAZp+0ytL0kOCNk8i8/J8FMKvIq7kqg==",
+ "requires": {}
+ },
"read-pkg": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-8.1.0.tgz",
diff --git a/package.json b/package.json
index 6cb2474bc..744d6e339 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,7 @@
"react-dom": "^18.2.0",
"react-redux": "^8.0.2",
"react-router-dom": "^6.18.0",
+ "react-virtuoso": "^4.9.0",
"redux": "^4.2.0",
"run": "^1.4.0",
"stream-browserify": "^3.0.0",
@@ -95,6 +96,7 @@
"@types/jest-axe": "^3.5.4",
"@types/material-ui": "^0.21.12",
"@types/node": "^18.6.1",
+ "@types/react-window": "^1.8.8",
"@typescript-eslint/eslint-plugin": "^5.31.0",
"@typescript-eslint/parser": "^5.31.0",
"babel-loader": "^8.2.5",
diff --git a/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap b/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap
index afbd6303b..7705a12dc 100644
--- a/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap
+++ b/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap
@@ -142,902 +142,924 @@ exports[`Results View The table should match snapshot and other elements should
/>
-
-
- opt
-
-
- e10s
-
-
- fission
-
-
- stylo
-
-
- webrender
-
-
-
-
-
-
-
- 704.84
-
- ms
-
-
-
- <
-
-
-
- 712.44
-
- ms
-
-
-
-
-
-
- Improvement
-
-
-
-
- 1.08
- %
-
-
-
-
- Low
-
-
-
-
-
- B:
-
-
- 1
-
-
-
-
- N:
-
-
- 1
-
-
-
-
-
-
-
-
-
-
- 776.97
-
- ms
-
-
-
- <
-
-
-
- 791.34
-
- ms
-
-
-
-
- 1.85
- %
-
-
-
-
- Medium
-
-
-
-
-
- B:
-
-
- 1
-
-
-
-
- N:
-
-
- 1
-
-
-
-
-
-
-
-
-
-
- 643.54
-
- ms
-
-
-
- >
-
-
-
- 628.09
-
- ms
-
-
-
- -
-
-
-
-
- -2.4
- %
-
-
-
-
- High
-
-
-
-
-
- B:
-
-
- 1
-
-
-
-
- N:
-
-
- 1
-
-
-
-
-
-
+
+
+ 704.84
+
+ ms
+
+
+
+ <
+
+
+
+ 712.44
+
+ ms
+
+
+
+
+
+
+ Improvement
+
+
+
+
+ 1.08
+ %
+
+
+
+
+ Low
+
+
+
+
+
+ B:
+
+
+ 1
+
+
+
+
+ N:
+
+
+ 1
+
+
+
+
+
+
+
-
-
-
-
-
-
- 643.54
-
- ms
-
-
-
- >
-
-
-
- 628.09
-
- ms
-
-
-
- -
-
-
-
-
- -2.4
- %
-
-
-
-
-
-
-
-
-
- B:
-
-
- 1
-
-
-
-
- N:
-
-
- 1
-
-
-
-
-
+
+
+ 643.54
+
+ ms
+
+
+
+ >
+
+
+
+ 628.09
+
+ ms
+
+
+
+ -
+
+
+
+
+ -2.4
+ %
+
+
+
+
+ High
+
+
+
+
+
+ B:
+
+
+ 1
+
+
+
+
+ N:
+
+
+ 1
+
+
+
+
+
+
+
+
+
+ 643.54
+
+ ms
+
+
+
+ >
+
+
+
+ 628.09
+
+ ms
+
+
+
+ -
+
+
+
+
+ -2.4
+ %
+
+
+
+
+
+
+
+
+
+ B:
+
+
+ 1
+
+
+
+
+ N:
+
+
+ 1
+
+
+
+
+
+
-
diff --git a/src/__tests__/CompareResults/__snapshots__/ResultsTable.test.tsx.snap b/src/__tests__/CompareResults/__snapshots__/ResultsTable.test.tsx.snap
index b895bbf4f..c786f7e3f 100644
--- a/src/__tests__/CompareResults/__snapshots__/ResultsTable.test.tsx.snap
+++ b/src/__tests__/CompareResults/__snapshots__/ResultsTable.test.tsx.snap
@@ -1099,946 +1099,975 @@ exports[`Results Table Should match snapshot 1`] = `
/>
-
-
- opt
-
-
- e10s
-
-
- fission
-
-
- stylo
-
-
- webrender
-
-
-
-
-
-
-
-
- 704.84
-
- ms
-
-
-
- <
-
-
-
- 712.44
-
- ms
-
-
-
-
-
-
- Improvement
-
-
-
-
- 1.08
- %
-
-
-
-
- Low
-
-
-
-
-
- B:
-
-
- 1
-
-
-
-
- N:
-
-
- 1
-
-
-
-
-
-
-
-
-
- 776.97
-
- ms
-
-
-
- <
-
-
-
- 791.34
-
- ms
-
-
-
-
- 1.85
- %
-
-
-
-
- Medium
-
-
-
-
-
- B:
-
-
- 1
-
-
-
-
- N:
-
-
- 1
-
-
-
-
-
-
-
-
-
-
- 643.54
-
- ms
-
-
-
- >
-
-
-
- 628.09
-
- ms
-
-
-
- -
-
-
-
-
- -2.4
- %
-
-
-
-
- High
-
-
-
-
-
- B:
-
-
- 1
-
-
-
-
- N:
-
-
- 1
-
-
-
-
-
+
+
+ 776.97
+
+ ms
+
+
+
+ <
+
+
+
+ 791.34
+
+ ms
+
+
+
+
+ 1.85
+ %
+
+
+
+
+ Medium
+
+
+
+
+
+ B:
+
+
+ 1
+
+
+
+
+ N:
+
+
+ 1
+
+
+
+
+
+
+
+
+
+ 643.54
+
+ ms
+
+
+
+ >
+
+
+
+ 628.09
+
+ ms
+
+
+
+ -
+
+
+
+
+ -2.4
+ %
+
+
+
+
+ High
+
+
+
+
+
+ B:
+
+
+ 1
+
+
+
+
+ N:
+
+
+ 1
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
- 643.54
-
- ms
-
-
-
- >
-
-
-
- 628.09
-
- ms
-
-
-
- -
-
-
-
-
- -2.4
- %
-
-
-
-
-
-
-
-
-
- B:
-
-
- 1
-
-
-
-
- N:
-
-
- 1
-
-
-
-
-
-
diff --git a/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap b/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap
index fe9bbfe74..17b1e16e5 100644
--- a/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap
+++ b/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap
@@ -340,902 +340,924 @@ exports[`Results View The table should match snapshot and other elements should
/>
-
-
- opt
-
-
- e10s
-
-
- fission
-
-
- stylo
-
-
- webrender
-
-
-
-
-
-
-
-
- 704.84
-
- ms
-
-
-
- <
-
-
-
- 712.44
-
- ms
-
-
-
-
-
-
- Improvement
-
-
-
-
- 1.08
- %
-
-
-
-
- Low
-
-
-
-
- B:
-
-
- 1
-
-
-
-
- N:
-
-
- 1
-
-
-
-
-
-
-
-
-
-
- 776.97
-
- ms
-
-
-
- <
-
-
-
- 791.34
-
- ms
-
-
-
-
- 1.85
- %
-
-
-
-
- Medium
-
-
-
-
-
- B:
-
-
- 1
-
-
-
-
- N:
-
-
- 1
-
-
-
-
-
-
-
-
-
-
- 643.54
-
- ms
-
-
-
- >
-
-
-
- 628.09
-
- ms
-
-
-
- -
-
-
-
-
- -2.4
- %
-
-
-
-
- High
-
-
-
-
-
- B:
-
-
- 1
-
-
-
-
- N:
-
-
- 1
-
-
-
-
-
-
+
+
+ 704.84
+
+ ms
+
+
+
+ <
+
+
+
+ 712.44
+
+ ms
+
+
+
+
+
+
+ Improvement
+
+
+
+
+ 1.08
+ %
+
+
+
+
+ Low
+
+
+
+
+
+ B:
+
+
+ 1
+
+
+
+
+ N:
+
+
+ 1
+
+
+
+
+
+
+
-
-
-
-
-
-
- 643.54
-
- ms
-
-
-
- >
-
-
-
- 628.09
-
- ms
-
-
-
- -
-
-
-
-
- -2.4
- %
-
-
-
-
-
-
-
-
-
- B:
-
-
- 1
-
-
-
-
- N:
-
-
- 1
-
-
-
-
-
+
+
+ 643.54
+
+ ms
+
+
+
+ >
+
+
+
+ 628.09
+
+ ms
+
+
+
+ -
+
+
+
+
+ -2.4
+ %
+
+
+
+
+ High
+
+
+
+
+
+ B:
+
+
+ 1
+
+
+
+
+ N:
+
+
+ 1
+
+
+
+
+
+
+
+
+
+ 643.54
+
+ ms
+
+
+
+ >
+
+
+
+ 628.09
+
+ ms
+
+
+
+ -
+
+
+
+
+ -2.4
+ %
+
+
+
+
+
+
+
+
+
+ B:
+
+
+ 1
+
+
+
+
+ N:
+
+
+ 1
+
+
+
+
+
+
-
diff --git a/src/__tests__/utils/test-utils.tsx b/src/__tests__/utils/test-utils.tsx
index adebb0cea..7ebb2834a 100644
--- a/src/__tests__/utils/test-utils.tsx
+++ b/src/__tests__/utils/test-utils.tsx
@@ -9,6 +9,7 @@ import { SnackbarProvider } from 'notistack';
import { Provider } from 'react-redux';
import { RouterProvider, createBrowserRouter } from 'react-router-dom';
import type { LoaderFunction } from 'react-router-dom';
+import { VirtuosoMockContext } from 'react-virtuoso';
import SnackbarCloseButton from '../../components/Shared/SnackbarCloseButton';
import getProtocolTheme from '../../theme/protocolTheme';
@@ -24,15 +25,19 @@ export function render(ui: React.ReactElement, themeConfig?: ThemeConfig) {
return (
- (
-
- )}
+
- {children}
-
+ (
+
+ )}
+ >
+ {children}
+
+
);
diff --git a/src/components/CompareResults/ResultsTable.tsx b/src/components/CompareResults/ResultsTable.tsx
index b1e0416f1..f5e34717e 100644
--- a/src/components/CompareResults/ResultsTable.tsx
+++ b/src/components/CompareResults/ResultsTable.tsx
@@ -1,6 +1,7 @@
import { useMemo, useState, memo } from 'react';
import Box from '@mui/material/Box';
+import { Virtuoso } from 'react-virtuoso';
import type { compareView, compareOverTimeView } from '../../common/constants';
import { useAppSelector } from '../../hooks/app';
@@ -236,15 +237,28 @@ function ResultsTable({
onToggleFilter={onToggleFilter}
onClearFilter={onClearFilter}
/>
- {processedResults.map((res) => (
-
- ))}
+ res.key}
+ itemContent={(_, res) => (
+
+ )}
+ />
{processedResults.length == 0 && }