Hoppa till innehåll

ReactCompileripraktiken:vaddengör,vaddenintegörochnärdetärvärtattslå

De flesta som skrivit React ett tag har en komplicerad relation till useMemo och useCallback. De behövs ibland, men det är sällan uppenbart när. Så antingen läggs de in överallt för säkerhets skull, eller så hoppar man över dem och hoppas att ingen märker att listan med 400 rader ritas om varje gång någon skriver i sökfältet.

React Compiler är Reacts försök att göra det valet åt dig. Version 1.0 släpptes i oktober 2025 efter flera år i produktion hos Meta. Frågan för de flesta team är därmed inte längre om det fungerar utan om det är värt att slå på.

Vad kompilatorn gör

React Compiler är ett byggsteg, ett Babel-plugin, som analyserar dina komponenter och hooks och skriver om dem så att värden och funktioner cachas mellan renderingar när det är säkert att göra det.

I praktiken innebär det att den gör tre saker som du annars gjort för hand:

  • Memoizerar beräknade värden, som useMemo fast automatiskt och med korrekt beroendelista.
  • Behåller referens till funktioner mellan renderingar, som useCallback.
  • Hoppar över omrendering av barnkomponenter vars props inte ändrats, som React.memo.

Skillnaden mot att göra det manuellt är att kompilatorn analyserar hela komponenten och kan memoizera på en finare nivå än en människa orkar. Den kan cacha ett enskilt JSX-uttryck mitt i en komponent, inte bara hela returvärdet.

Resultatet är att en komponent som tidigare renderades om i onödan tio gånger vid varje tangenttryckning nu bara renderas om när något den faktiskt använder har ändrats.

Vad den inte gör

Den gör inte långsam kod snabb. Om en komponent gör tunga beräkningar vid varje rendering blir de beräkningarna cachade, men om de tunga beräkningarna ligger i en effekt, ett nätverksanrop eller i hur du strukturerat din data hjälper kompilatorn inte alls.

Den fixar inte trasig kod. Kompilatorn bygger på att din kod följer Rules of React: komponenter och hooks ska vara rena, props och state ska inte muteras, hooks ska anropas i samma ordning varje gång. Bryter en komponent mot reglerna hoppar kompilatorn över just den komponenten och lämnar den orörd. Din app fortsätter fungera som förut, men du får inte optimeringen där.

Den ersätter inte allt. Vissa mönster där du memoizerar av korrekthetsskäl snarare än prestandaskäl, som att hålla en stabil referens för att en extern bibliotekseffekt inte ska trigga i onödan, kan fortfarande behöva manuell hantering. React-teamet rekommenderar att behålla befintlig useMemo och useCallback under övergången och ta bort dem stegvis när man verifierat att kompilatorn täcker fallet.

Att slå på den i Next.js

I Next.js 16 är stödet stabilt och konfigurationen kort:

// next.config.ts
const nextConfig = {
  reactCompiler: true,
};

export default nextConfig;

Plus paketet:

npm install babel-plugin-react-compiler

Kompilatorn kräver React 19 för full funktionalitet. På React 17 och 18 går det att köra med paketet react-compiler-runtime, men då är det rimligt att fråga sig om uppgraderingen till 19 inte är det bättre första steget.

Vill du inte slå på för hela projektet direkt finns läget annotation, där bara komponenter märkta med direktivet "use memo" kompileras. Omvänt kan du undanta en enskild komponent med "use no memo" om den bråkar.

En sak att känna till: eftersom kompilatorn är ett Babel-plugin körs det utanför den ordinarie SWC- eller Turbopack-kedjan. Next.js begränsar det till de filer som behöver det, men räkna med något längre byggtider och mät innan och efter.

Lint först, kompilator sedan

Det bästa förarbetet är att uppdatera eslint-plugin-react-hooks till version 6 eller senare. Den innehåller reglerna som kompilatorn själv använder för att avgöra om en komponent går att optimera, och den flaggar precis de ställen som annars skulle hoppas över tyst.

Kör lint på hela kodbasen innan du slår på kompilatorn. Antalet fel är en bra indikator på hur mycket av nyttan du kommer få direkt och hur mycket som kräver städning.

Vanliga saker som dyker upp:

  • state eller props som muteras direkt istället för att kopieras
  • värden som läses från refs under rendering
  • villkorligt anropade hooks
  • komponenter som skapar andra komponenter inuti sig

Inget av det är nya regler. Kompilatorn gör bara konsekvensen av att bryta mot dem synlig.

Hur du vet om det gav något

Om ni vill veta om det gjorde skillnad, och inte bara att flaggan är på:

  1. Mät INP i fält före och efter, via Search Console eller ert RUM-verktyg. INP är den Core Web Vital som påverkas mest av onödiga omrenderingar.
  2. Använd React DevTools Profiler på ett par tunga vyer och jämför antalet renderingar för samma interaktion.
  3. Titta efter komponenter i DevTools som märks med "Memo ✨". Det visar var kompilatorn gjort något.
  4. Håll koll på bundle-storlek och byggtid. Kompilerad kod är något större, i de flesta fall försumbart, men det är värt att veta.

Om ni inte ser någon skillnad hade appen troligen inga problem med omrenderingar från början. Det är ett fullt rimligt utfall.

När det är värt det

Kompilatorn är mest värd i appar med mycket interaktivt tillstånd: dashboards, redigeringsverktyg, formulär med många fält, listor som filtreras i realtid. Där ligger de flesta prestandaproblem som memoization löser.

På en innehållssajt eller en landningssida där de flesta komponenter är serverkomponenter och renderas en gång finns lite att vinna. Det skadar inte att slå på den, men förvänta er inte att märka något.

För nya projekt på React 19 och Next.js 16 är rekommendationen enkel: slå på den från dag ett, kör lint strikt och skriv inte manuell memoization förrän profileringen visar att det behövs. Då försvinner frågan om useMemo ur kodgranskningarna, och koden blir lättare att läsa.

React Compiler tar bort en kategori av arbete som få gillade. Den gör det försiktigt, hoppar över kod den inte litar på och kräver att man följer regler som varit rekommenderade sedan hooks kom. Prestandavinsten varierar med appen; att slippa diskussionen om memoization får man oavsett.

Källor