From 34778ec591b8bc9b89c6cf8a5c6b6aeea1fc742a Mon Sep 17 00:00:00 2001 From: Alexander Alemayhu Date: Tue, 19 May 2026 19:39:04 +0200 Subject: [PATCH] perf: enable React Compiler for the web app Adds babel-plugin-react-compiler to the Vite React plugin's Babel chain. Auto-memoizes components and hooks, reducing re-renders and shaving main-thread work on interaction-heavy pages. Verified: pnpm typecheck, pnpm build (5.7s), pnpm lint clean, 774 tests pass. Note: this targets INP/runtime perf, not LCP. The render-blocking + unused-JS work from the PageSpeed report is a separate PR. Co-Authored-By: Claude Opus 4.7 (1M context) --- pnpm-lock.yaml | 38 +++++++++++++++++++++++++++----------- web/package.json | 1 + web/vite.config.ts | 6 +++++- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 010a53d94..9900eda0e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -416,7 +416,7 @@ importers: version: 8.0.2(terser@5.47.1)(vite@8.0.13(@types/node@25.8.0)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.22.0)(yaml@2.9.0)) '@vitejs/plugin-react': specifier: ^6.0.2 - version: 6.0.2(vite@8.0.13(@types/node@25.8.0)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.22.0)(yaml@2.9.0)) + version: 6.0.2(babel-plugin-react-compiler@1.0.0)(vite@8.0.13(@types/node@25.8.0)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.22.0)(yaml@2.9.0)) '@vitest/coverage-v8': specifier: ^4.1.5 version: 4.1.6(vitest@4.1.6) @@ -426,6 +426,9 @@ importers: autoprefixer: specifier: ^10.5.0 version: 10.5.0(postcss@8.5.14) + babel-plugin-react-compiler: + specifier: ^1.0.0 + version: 1.0.0 concurrently: specifier: ^9.2.1 version: 9.2.1 @@ -3548,6 +3551,9 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + babel-plugin-react-compiler@1.0.0: + resolution: {integrity: sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==} + babel-preset-current-node-syntax@1.2.0: resolution: {integrity: sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==} peerDependencies: @@ -8677,7 +8683,7 @@ snapshots: '@babel/types': 7.29.0 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -8729,7 +8735,7 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 lodash.debounce: 4.0.8 resolve: 1.22.12 transitivePeerDependencies: @@ -9390,7 +9396,7 @@ snapshots: '@babel/parser': 7.29.3 '@babel/template': 7.28.6 '@babel/types': 7.29.0 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -11596,10 +11602,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-react@6.0.2(vite@8.0.13(@types/node@25.8.0)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.22.0)(yaml@2.9.0))': + '@vitejs/plugin-react@6.0.2(babel-plugin-react-compiler@1.0.0)(vite@8.0.13(@types/node@25.8.0)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.22.0)(yaml@2.9.0))': dependencies: '@rolldown/pluginutils': 1.0.1 vite: 8.0.13(@types/node@25.8.0)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.22.0)(yaml@2.9.0) + optionalDependencies: + babel-plugin-react-compiler: 1.0.0 '@vitest/coverage-v8@4.1.6(vitest@4.1.6)': dependencies: @@ -11881,6 +11889,10 @@ snapshots: transitivePeerDependencies: - supports-color + babel-plugin-react-compiler@1.0.0: + dependencies: + '@babel/types': 7.29.0 + babel-preset-current-node-syntax@1.2.0(@babel/core@7.29.0): dependencies: '@babel/core': 7.29.0 @@ -11987,7 +11999,7 @@ snapshots: dependencies: bytes: 3.1.2 content-type: 1.0.5 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 http-errors: 2.0.1 iconv-lite: 0.7.2 on-finished: 2.4.1 @@ -12675,6 +12687,10 @@ snapshots: dependencies: ms: 2.1.2 + debug@4.4.3: + dependencies: + ms: 2.1.3 + debug@4.4.3(supports-color@5.5.0): dependencies: ms: 2.1.3 @@ -13018,7 +13034,7 @@ snapshots: content-type: 1.0.5 cookie: 0.7.2 cookie-signature: 1.2.2 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 depd: 2.0.0 encodeurl: 2.0.0 escape-html: 1.0.3 @@ -13098,7 +13114,7 @@ snapshots: finalhandler@2.1.1: dependencies: - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 @@ -14928,7 +14944,7 @@ snapshots: micromark@4.0.2: dependencies: '@types/debug': 4.1.13 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 decode-named-character-reference: 1.3.0 devlop: 1.1.0 micromark-core-commonmark: 2.0.3 @@ -15962,7 +15978,7 @@ snapshots: router@2.2.0: dependencies: - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 depd: 2.0.0 is-promise: 4.0.0 parseurl: 1.3.3 @@ -16029,7 +16045,7 @@ snapshots: send@1.2.1: dependencies: - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 diff --git a/web/package.json b/web/package.json index 930c536d2..bb8fff619 100644 --- a/web/package.json +++ b/web/package.json @@ -70,6 +70,7 @@ "@vitest/coverage-v8": "^4.1.5", "@vitest/ui": "^4.1.6", "autoprefixer": "^10.5.0", + "babel-plugin-react-compiler": "^1.0.0", "concurrently": "^9.2.1", "cors": "^2.8.6", "cross-env": "^10.1.0", diff --git a/web/vite.config.ts b/web/vite.config.ts index cf1104577..134b0bcb1 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -31,7 +31,11 @@ export default defineConfig(({ command, mode }) => { return { plugins: [ - react(), + react({ + babel: { + plugins: ['babel-plugin-react-compiler'], + }, + }), svgr({ // SVG as React components svgrOptions: {