diff --git a/README.md b/README.md index 8af91ec83..88fb30ddd 100644 --- a/README.md +++ b/README.md @@ -368,143 +368,7 @@ This package uses [exports of package.json](https://nodejs.org/api/packages.html ### Benchmark -A rough benchmark with vitest running on headless Chromium. - -> [!WARNING] -> Each virtualization library has different characteristics. Their performance on browser varies depending on library settings and situations. - -```sh -npm install -npm run bench -``` - -This is a result in my Intel MacBook Pro 2018. - -``` - ✓ index.bench.tsx (48) 264126ms - ✓ mount / 1000 items / same sized items (6) 5167ms - name hz min max mean p75 p99 p995 p999 rme samples - · virtua@0.39.0 (elements) 144.38 5.2000 27.6000 6.9260 6.6000 27.6000 27.6000 27.6000 ±9.91% 73 fastest - · virtua@0.39.0 (render prop) 61.9133 12.7000 21.2000 16.1516 16.9000 21.2000 21.2000 21.2000 ±4.49% 31 - · react-virtualized@9.22.5 31.6456 29.3000 33.8000 31.6000 33.4000 33.8000 33.8000 33.8000 ±2.64% 16 - · react-window@1.8.10 27.6954 30.4000 86.4000 36.1071 33.3000 86.4000 86.4000 86.4000 ±23.21% 14 slowest - · react-virtuoso@4.12.3 36.6512 25.4000 29.7000 27.2842 28.4000 29.7000 29.7000 29.7000 ±2.44% 19 - · @tanstack/react-virtual@3.11.0 28.3286 33.4000 38.1000 35.3000 36.4000 38.1000 38.1000 38.1000 ±2.35% 15 - ✓ mount / 1000 items / dynamic sized items (6) 4825ms - name hz min max mean p75 p99 p995 p999 rme samples - · virtua@0.39.0 (elements) 27.5645 33.6000 38.7000 36.2786 37.3000 38.7000 38.7000 38.7000 ±2.50% 14 - · virtua@0.39.0 (render prop) 27.7338 33.7000 39.1000 36.0571 37.5000 39.1000 39.1000 39.1000 ±2.79% 14 fastest - · react-virtualized@9.22.5 21.3717 44.1000 49.3000 46.7909 48.9000 49.3000 49.3000 49.3000 ±2.89% 11 - · react-window@1.8.10 20.6884 43.3000 64.2000 48.3364 47.7000 64.2000 64.2000 64.2000 ±10.12% 11 slowest - · react-virtuoso@4.12.3 24.1411 38.9000 43.8000 41.4231 42.8000 43.8000 43.8000 43.8000 ±2.40% 13 - · @tanstack/react-virtual@3.11.0 21.5433 44.4000 49.4000 46.4182 47.3000 49.4000 49.4000 49.4000 ±1.96% 11 - ✓ mount / 1000 items / heavy DOM (6) 17132ms - name hz min max mean p75 p99 p995 p999 rme samples - · virtua@0.39.0 (elements) 16.4204 56.3000 69.2000 60.9000 61.7000 69.2000 69.2000 69.2000 ±3.96% 10 fastest - · virtua@0.39.0 (render prop) 10.4756 77.7000 106.60 95.4600 103.00 106.60 106.60 106.60 ±8.07% 10 - · react-virtualized@9.22.5 4.8735 160.90 361.70 205.19 201.80 361.70 361.70 361.70 ±21.34% 10 - · react-window@1.8.10 4.5566 201.40 230.40 219.46 225.40 230.40 230.40 230.40 ±2.97% 10 - · react-virtuoso@4.12.3 4.8400 200.10 215.30 206.61 209.70 215.30 215.30 215.30 ±1.68% 10 - · @tanstack/react-virtual@3.11.0 3.3565 264.10 426.10 297.93 295.00 426.10 426.10 426.10 ±11.10% 10 slowest - ✓ mount / 1000 items / heavy JS (6) 48444ms - name hz min max mean p75 p99 p995 p999 rme samples - · virtua@0.39.0 (elements) 3.4565 262.00 317.00 289.31 293.50 317.00 317.00 317.00 ±3.97% 10 - · virtua@0.39.0 (render prop) 3.6686 266.80 278.10 272.58 276.80 278.10 278.10 278.10 ±1.10% 10 - · react-virtualized@9.22.5 1.6057 592.80 825.70 622.78 604.70 825.70 825.70 825.70 ±8.22% 10 slowest - · react-window@1.8.10 1.7930 532.50 638.80 557.72 565.10 638.80 638.80 638.80 ±4.01% 10 - · react-virtuoso@4.12.3 3.7942 240.60 292.90 263.56 276.20 292.90 292.90 292.90 ±4.77% 10 fastest - · @tanstack/react-virtual@3.11.0 1.7890 512.40 767.50 558.98 553.70 767.50 767.50 767.50 ±9.66% 10 - ✓ mount / 100000 items / same sized items (6) 30778ms - name hz min max mean p75 p99 p995 p999 rme samples - · virtua@0.39.0 (elements) 1.8634 478.40 956.20 536.64 493.40 956.20 956.20 956.20 ±19.68% 10 slowest - · virtua@0.39.0 (render prop) 3.5119 264.30 301.30 284.75 291.50 301.30 301.30 301.30 ±2.56% 10 fastest - · react-virtualized@9.22.5 3.4047 284.80 302.10 293.71 296.90 302.10 302.10 302.10 ±1.27% 10 - · react-window@1.8.10 3.2766 296.60 317.00 305.19 309.80 317.00 317.00 317.00 ±1.71% 10 - · react-virtuoso@4.12.3 3.4557 275.30 321.00 289.38 289.00 321.00 321.00 321.00 ±3.42% 10 - · @tanstack/react-virtual@3.11.0 3.0618 314.70 341.80 326.60 332.00 341.80 341.80 341.80 ±1.85% 10 - ✓ mount / 100000 items / dynamic sized items (6) 32889ms - name hz min max mean p75 p99 p995 p999 rme samples - · virtua@0.39.0 (elements) 1.7017 486.60 1,349.20 587.64 510.30 1,349.20 1,349.20 1,349.20 ±32.59% 10 slowest - · virtua@0.39.0 (render prop) 3.3421 284.50 313.30 299.21 303.60 313.30 313.30 313.30 ±2.12% 10 - · react-virtualized@9.22.5 3.3629 285.90 314.80 297.36 300.60 314.80 314.80 314.80 ±1.93% 10 - · react-window@1.8.10 3.2632 300.40 321.10 306.45 310.40 321.10 321.10 321.10 ±1.58% 10 - · react-virtuoso@4.12.3 3.3731 285.70 312.50 296.46 307.20 312.50 312.50 312.50 ±2.53% 10 fastest - · @tanstack/react-virtual@3.11.0 2.4953 307.40 1,144.40 400.76 329.90 1,144.40 1,144.40 1,144.40 ±46.67% 10 - ✓ mount / 100000 items / heavy DOM (6) 45815ms - name hz min max mean p75 p99 p995 p999 rme samples - · virtua@0.39.0 (elements) 1.8797 513.50 552.90 531.99 541.00 552.90 552.90 552.90 ±1.74% 10 - · virtua@0.39.0 (render prop) 2.8553 327.80 364.00 350.22 359.30 364.00 364.00 364.00 ±2.52% 10 fastest - · react-virtualized@9.22.5 1.8016 423.60 1,201.20 555.07 461.10 1,201.20 1,201.20 1,201.20 ±32.57% 10 - · react-window@1.8.10 2.1025 439.20 497.30 475.63 487.20 497.30 497.30 497.30 ±2.74% 10 - · react-virtuoso@4.12.3 2.1951 442.60 467.50 455.57 459.60 467.50 467.50 467.50 ±1.20% 10 - · @tanstack/react-virtual@3.11.0 1.4734 547.00 1,736.80 678.71 571.30 1,736.80 1,736.80 1,736.80 ±39.19% 10 slowest - ✓ mount / 100000 items / heavy JS (6) 78926ms - name hz min max mean p75 p99 p995 p999 rme samples - · virtua@0.39.0 (elements) 1.0982 730.80 2,364.80 910.58 768.60 2,364.80 2,364.80 2,364.80 ±40.15% 10 - · virtua@0.39.0 (render prop) 1.8695 510.80 561.60 534.89 552.10 561.60 561.60 561.60 ±2.43% 10 fastest - · react-virtualized@9.22.5 1.0132 813.90 2,005.70 986.98 917.90 2,005.70 2,005.70 2,005.70 ±26.46% 10 slowest - · react-window@1.8.10 1.2407 769.60 864.50 806.01 858.50 864.50 864.50 864.50 ±3.46% 10 - · react-virtuoso@4.12.3 1.6482 504.20 1,332.60 606.73 531.50 1,332.60 1,332.60 1,332.60 ±30.12% 10 - · @tanstack/react-virtual@3.11.0 1.0522 769.70 2,150.60 950.36 821.90 2,150.60 2,150.60 2,150.60 ±32.16% 10 - - BENCH Summary - - virtua@0.39.0 (elements) - index.bench.tsx > mount / 1000 items / same sized items - 2.33x faster than virtua@0.39.0 (render prop) - 3.94x faster than react-virtuoso@4.12.3 - 4.56x faster than react-virtualized@9.22.5 - 5.10x faster than @tanstack/react-virtual@3.11.0 - 5.21x faster than react-window@1.8.10 - - virtua@0.39.0 (render prop) - index.bench.tsx > mount / 1000 items / dynamic sized items - 1.01x faster than virtua@0.39.0 (elements) - 1.15x faster than react-virtuoso@4.12.3 - 1.29x faster than @tanstack/react-virtual@3.11.0 - 1.30x faster than react-virtualized@9.22.5 - 1.34x faster than react-window@1.8.10 - - virtua@0.39.0 (elements) - index.bench.tsx > mount / 1000 items / heavy DOM - 1.57x faster than virtua@0.39.0 (render prop) - 3.37x faster than react-virtualized@9.22.5 - 3.39x faster than react-virtuoso@4.12.3 - 3.60x faster than react-window@1.8.10 - 4.89x faster than @tanstack/react-virtual@3.11.0 - - react-virtuoso@4.12.3 - index.bench.tsx > mount / 1000 items / heavy JS - 1.03x faster than virtua@0.39.0 (render prop) - 1.10x faster than virtua@0.39.0 (elements) - 2.12x faster than react-window@1.8.10 - 2.12x faster than @tanstack/react-virtual@3.11.0 - 2.36x faster than react-virtualized@9.22.5 - - virtua@0.39.0 (render prop) - index.bench.tsx > mount / 100000 items / same sized items - 1.02x faster than react-virtuoso@4.12.3 - 1.03x faster than react-virtualized@9.22.5 - 1.07x faster than react-window@1.8.10 - 1.15x faster than @tanstack/react-virtual@3.11.0 - 1.88x faster than virtua@0.39.0 (elements) - - react-virtuoso@4.12.3 - index.bench.tsx > mount / 100000 items / dynamic sized items - 1.00x faster than react-virtualized@9.22.5 - 1.01x faster than virtua@0.39.0 (render prop) - 1.03x faster than react-window@1.8.10 - 1.35x faster than @tanstack/react-virtual@3.11.0 - 1.98x faster than virtua@0.39.0 (elements) - - virtua@0.39.0 (render prop) - index.bench.tsx > mount / 100000 items / heavy DOM - 1.30x faster than react-virtuoso@4.12.3 - 1.36x faster than react-window@1.8.10 - 1.52x faster than virtua@0.39.0 (elements) - 1.58x faster than react-virtualized@9.22.5 - 1.94x faster than @tanstack/react-virtual@3.11.0 - - virtua@0.39.0 (render prop) - index.bench.tsx > mount / 100000 items / heavy JS - 1.13x faster than react-virtuoso@4.12.3 - 1.51x faster than react-window@1.8.10 - 1.70x faster than virtua@0.39.0 (elements) - 1.78x faster than @tanstack/react-virtual@3.11.0 - 1.85x faster than react-virtualized@9.22.5 -``` +WIP ## Contribute diff --git a/package-lock.json b/package-lock.json index 7558cc204..90f77311f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -53,7 +53,6 @@ "@vitejs/plugin-react": "^4.3.3", "@vitejs/plugin-vue": "^5.1.4", "@vitejs/plugin-vue-jsx": "^4.0.1", - "@vitest/browser": "^2.1.8", "babel-preset-solid": "^1.9.3", "cmdk": "^1.0.4", "concurrently": "^9.0.1", @@ -99,7 +98,6 @@ "vite": "5.1.8", "vite-plugin-solid": "^2.11.0", "vitest": "^2.1.3", - "vitest-browser-react": "^0.0.4", "vue": "^3.4.34", "vue-eslint-parser": "^9.4.3", "wait-on": "^8.0.1" @@ -861,6 +859,8 @@ "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.1.tgz", "integrity": "sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "cookie": "^0.7.2" } @@ -870,6 +870,8 @@ "resolved": "https://registry.npmjs.org/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz", "integrity": "sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "statuses": "^2.0.1" } @@ -879,6 +881,8 @@ "resolved": "https://registry.npmjs.org/@bundled-es-modules/tough-cookie/-/tough-cookie-0.1.6.tgz", "integrity": "sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@types/tough-cookie": "^4.0.5", "tough-cookie": "^4.1.4" @@ -889,6 +893,8 @@ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -1814,6 +1820,8 @@ "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.0.2.tgz", "integrity": "sha512-KJLUHOaKnNCYzwVbryj3TNBxyZIrr56fR5N45v6K9IPrbT6B7DcudBMfylkV1A8PUdJE15mybkEQyp2/ZUpxUA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@inquirer/core": "^10.1.0", "@inquirer/type": "^3.0.1" @@ -1830,6 +1838,8 @@ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.0.tgz", "integrity": "sha512-I+ETk2AL+yAVbvuKx5AJpQmoaWhpiTFOg/UJb7ZkMAK4blmtG8ATh5ct+T/8xNld0CZG/2UhtkdMwpgvld92XQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@inquirer/figures": "^1.0.8", "@inquirer/type": "^3.0.1", @@ -1850,6 +1860,8 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -1865,6 +1877,8 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -1876,13 +1890,17 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/@inquirer/core/node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=14" }, @@ -1895,6 +1913,8 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -1909,6 +1929,8 @@ "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.8.tgz", "integrity": "sha512-tKd+jsmhq21AP1LhexC0pPwsCxEhGgAkg28byjJAd+xhmIs8LUX8JbUc3vBf3PhLxWiB5EvyBE5X7JSPAqMAqg==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=18" } @@ -1918,6 +1940,8 @@ "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.1.tgz", "integrity": "sha512-+ksJMIy92sOAiAccGpcKZUc3bYO07cADnscIxHBknEm3uNts3movSmBofc1908BNy5edKscxYeAdaX1NXkHS6A==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=18" }, @@ -3069,6 +3093,8 @@ "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.37.3.tgz", "integrity": "sha512-USvgCL/uOGFtVa6SVyRrC8kIAedzRohxIXN5LISlg5C5vLZCn7dgMFVSNhSF9cuBEFrm/O2spDWEZeMnw4ZXYg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@open-draft/deferred-promise": "^2.2.0", "@open-draft/logger": "^0.3.0", @@ -3367,13 +3393,17 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz", "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/@open-draft/logger": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz", "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "is-node-process": "^1.2.0", "outvariant": "^1.4.0" @@ -3383,7 +3413,9 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz", "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", @@ -3414,7 +3446,9 @@ "version": "1.0.0-next.28", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/@popperjs/core": { "version": "2.11.8", @@ -5527,6 +5561,8 @@ "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=12", "npm": ">=6" @@ -5707,7 +5743,9 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/@types/estree": { "version": "1.0.6", @@ -5871,7 +5909,9 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.5.tgz", "integrity": "sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/@types/tough-cookie": { "version": "4.0.5", @@ -6202,6 +6242,8 @@ "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-2.1.8.tgz", "integrity": "sha512-OWVvEJThRgxlNMYNVLEK/9qVkpRcLvyuKLngIV3Hob01P56NjPHprVBYn+rx4xAJudbM9yrCrywPIEuA3Xyo8A==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@testing-library/dom": "^10.4.0", "@testing-library/user-event": "^14.5.2", @@ -6238,6 +6280,8 @@ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.14.tgz", "integrity": "sha512-5c99P1WKTed11ZC0HMJOj6CDIue6F8ySu+bJL+85q1zBEIY8IklrJ1eiKC2NDRh3Ct3FcvmJPyQHb9erXMTJNw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } @@ -7834,6 +7878,8 @@ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">= 12" } @@ -8085,6 +8131,8 @@ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">= 0.6" } @@ -10999,6 +11047,8 @@ "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.9.0.tgz", "integrity": "sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } @@ -11128,7 +11178,9 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-4.0.3.tgz", "integrity": "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/hermes-estree": { "version": "0.25.1", @@ -11799,7 +11851,9 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/is-number": { "version": "7.0.0", @@ -15065,6 +15119,8 @@ "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=10" } @@ -15081,6 +15137,8 @@ "integrity": "sha512-jqimU18eVoVX8EdDipzgO5C7q2LnEuxe5fQcAhoa5nNy3/YBni70mIwUCO52kL72ZHYLMemdqJSj7e0QP4ltGw==", "dev": true, "hasInstallScript": true, + "optional": true, + "peer": true, "dependencies": { "@bundled-es-modules/cookie": "^2.0.1", "@bundled-es-modules/statuses": "^1.0.1", @@ -15124,6 +15182,8 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -15139,6 +15199,8 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -15155,6 +15217,8 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -15166,13 +15230,17 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/msw/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=8" } @@ -15182,6 +15250,8 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -15194,6 +15264,8 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.30.0.tgz", "integrity": "sha512-G6zXWS1dLj6eagy6sVhOMQiLtJdxQBHIA9Z6HFUNLOlr6MFOgzV8wvmidtPONfPtEUv0uZsy77XJNzTAfwPDaA==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=16" }, @@ -15212,6 +15284,8 @@ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": "^18.17.0 || >=20.5.0" } @@ -15788,7 +15862,9 @@ "version": "1.4.3", "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz", "integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/p-limit": { "version": "3.1.0", @@ -16000,7 +16076,9 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/path-type": { "version": "4.0.0", @@ -16350,6 +16428,8 @@ "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "punycode": "^2.3.1" }, @@ -16520,7 +16600,9 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -16970,7 +17052,9 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/resolve": { "version": "1.22.8", @@ -17459,6 +17543,8 @@ "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.0.tgz", "integrity": "sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", @@ -17696,6 +17782,8 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">= 0.8" } @@ -17794,7 +17882,9 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz", "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/string_decoder": { "version": "1.3.0", @@ -18712,6 +18802,8 @@ "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=6" } @@ -19090,6 +19182,8 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">= 4.0.0" } @@ -19190,6 +19284,8 @@ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -19530,34 +19626,6 @@ } } }, - "node_modules/vitest-browser-react": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vitest-browser-react/-/vitest-browser-react-0.0.4.tgz", - "integrity": "sha512-4uK8zgo5eHlhrBVEPX8ejRt8Bn4gzV6OZFTPdb1en3FtgjEhhst400XkIQHUC875Q90rOO5Tc4zPpCl8YXvoxg==", - "dev": true, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@types/react": ">18.0.0", - "@types/react-dom": ">18.0.0", - "@vitest/browser": ">=2.1.0", - "react": ">18.0.0", - "react-dom": ">18.0.0", - "vitest": ">=2.1.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, "node_modules/vitest/node_modules/magic-string": { "version": "0.30.12", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", @@ -20204,6 +20272,8 @@ "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=18" }, diff --git a/package.json b/package.json index fc0e1e887..df7e2b9e8 100644 --- a/package.json +++ b/package.json @@ -36,8 +36,7 @@ "scripts": { "build": "rollup -c", "tsc": "tsc -p . --noEmit", - "test": "vitest --run --project test --silent", - "bench": "vitest bench --run --project bench", + "test": "vitest --run --silent", "lint": "eslint 'src/**/*.{js,jsx,ts,tsx}'", "check:svelte": "svelte-check --tsconfig ./tsconfig.svelte.json", "storybook": "storybook dev -p 6006", @@ -101,7 +100,6 @@ "@vitejs/plugin-react": "^4.3.3", "@vitejs/plugin-vue": "^5.1.4", "@vitejs/plugin-vue-jsx": "^4.0.1", - "@vitest/browser": "^2.1.8", "babel-preset-solid": "^1.9.3", "cmdk": "^1.0.4", "concurrently": "^9.0.1", @@ -147,7 +145,6 @@ "vite": "5.1.8", "vite-plugin-solid": "^2.11.0", "vitest": "^2.1.3", - "vitest-browser-react": "^0.0.4", "vue": "^3.4.34", "vue-eslint-parser": "^9.4.3", "wait-on": "^8.0.1" diff --git a/stories/react/comparisons/components/virtua-render.tsx b/stories/react/comparisons/components/virtua-render.tsx deleted file mode 100644 index a538be427..000000000 --- a/stories/react/comparisons/components/virtua-render.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React, { Ref, memo, useImperativeHandle, useRef } from "react"; -import { VList, VListHandle } from "virtua"; -import { ListHandle, TestComponent } from "./common"; - -export const VirtuaList = memo( - ({ - count, - Component, - handle, - }: { - count: number; - Component: TestComponent; - handle?: Ref; - }) => { - const ref = useRef(null); - useImperativeHandle(handle, () => ({ - scrollToIndex: (i) => { - ref.current?.scrollToIndex(i); - }, - })); - - return ( - - {(i) => } - - ); - } -); diff --git a/stories/react/comparisons/index.bench.tsx b/stories/react/comparisons/index.bench.tsx deleted file mode 100644 index e7d251e83..000000000 --- a/stories/react/comparisons/index.bench.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import React, { ReactNode } from "react"; -import { bench, describe } from "vitest"; -import { render } from "vitest-browser-react"; -import { - DynamicItem, - HeavyDOMItem, - HeavyJsItem, - SimpleItem, -} from "./components/common"; -import { VirtuaList } from "./components/virtua"; -import { VirtuaList as VirtuaListRender } from "./components/virtua-render"; -import { ReactVirtualList } from "./components/react-virtual"; -import { ReactVirtuosoList } from "./components/react-virtuoso"; -import { ReactVirtualizedList } from "./components/react-virtualized"; -import { ReactWindowList } from "./components/react-window"; -import { version as VirtuaVersion } from "virtua/package.json"; -import { version as ReactVirtualizedVersion } from "react-virtualized/package.json"; -import { version as ReactWindowVirsion } from "react-window/package.json"; -import { version as ReactVirtuosoVirsion } from "react-virtuoso/package.json"; -import { version as ReactVirtualVersion } from "@tanstack/react-virtual/package.json"; - -const components: [string, typeof VirtuaList][] = [ - [`virtua@${VirtuaVersion} (elements)`, VirtuaList], - [`virtua@${VirtuaVersion} (render prop)`, VirtuaListRender], - [`react-virtualized@${ReactVirtualizedVersion}`, ReactVirtualizedList], - [`react-window@${ReactWindowVirsion}`, ReactWindowList], - [`react-virtuoso@${ReactVirtuosoVirsion}`, ReactVirtuosoList], - [`@tanstack/react-virtual@${ReactVirtualVersion}`, ReactVirtualList], -]; - -const itemComponents: [string, typeof SimpleItem][] = [ - ["fixed size", SimpleItem], - ["dynamic size", DynamicItem], - ["heavy DOM", HeavyDOMItem], - ["heavy JS", HeavyJsItem], -]; - -const VIEWPORT_SIZE = 50 * 30; - -const Viewport = ({ children }: { children: ReactNode }) => ( -
{children}
-); - -[1000, 100000].forEach((count) => { - itemComponents.forEach(([name, ItemComponent]) => { - describe(`mount / ${count} items (${name})`, () => { - components.forEach(([name, Component]) => { - bench(name, async () => { - const screen = render( - - - - ); - - await Promise.all([screen.getByText("0"), screen.getByText("29")]); - }); - }); - }); - }); -}); diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 000000000..1ecc2702c --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + root: "src", + environment: "jsdom", + clearMocks: true, + // https://github.com/testing-library/vue-testing-library/issues/296 + globals: true, + }, +}); diff --git a/vitest.workspace.ts b/vitest.workspace.ts deleted file mode 100644 index 541e39501..000000000 --- a/vitest.workspace.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { defineWorkspace } from "vitest/config"; - -export default defineWorkspace([ - { - test: { - name: "test", - root: "src", - environment: "jsdom", - clearMocks: true, - // https://github.com/testing-library/vue-testing-library/issues/296 - globals: true, - }, - }, - { - test: { - name: "bench", - root: "stories/react/comparisons", - browser: { - provider: "playwright", - name: "chromium", - enabled: true, - headless: true, - }, - }, - }, -]);