Optimization Passes
React Compiler includes numerous optimization passes that transform code at different stages of compilation. This guide covers the major passes and their purposes.Pass Categories
Optimization passes are organized into several categories:- HIR Construction & SSA (passes 1-3)
- Early Optimization (passes 4-5)
- Type & Effect Inference (passes 6-10)
- Reactive Scope Construction (passes 11-20)
- Reactive Function Optimization (passes 22-29)
- Code Generation (passes 30-31)
- Optional Transformations (feature-gated)
Early Optimization Passes
Constant Propagation
File:src/Optimization/ConstantPropagation.ts
Implements sparse conditional constant propagation (SCCP).
What it does:
- Replaces variables with known constant values
- Evaluates constant expressions at compile time
- Simplifies conditional branches with constant tests
Dead Code Elimination
File:src/Optimization/DeadCodeElimination.ts
Removes unreferenced instructions and unreachable code.
What it does:
- Identifies unreferenced values
- Removes instructions with no side effects that aren’t used
- Eliminates unreachable basic blocks
Instruction Reordering
File:src/Optimization/InstructionReordering.tsFlag:
enableInstructionReordering
Reorders instructions to improve memoization opportunities.
What it does:
- Moves independent instructions earlier
- Groups related computations
- Improves reactive scope boundaries
Type Inference
InferTypes
File:src/TypeInference/InferTypes.ts
Infers types through constraint-based unification.
Type Categories:
Effect Inference
AnalyseFunctions
File:src/Inference/AnalyseFunctions.ts
Analyzes nested function expressions and arrow functions.
What it does:
- Determines what values functions capture
- Identifies function effects (pure, mutating, etc.)
- Marks functions that can be memoized
InferMutationAliasingEffects
File:src/Inference/InferMutationAliasingEffects.ts
Infers mutation and aliasing effects through abstract interpretation.
Effects tracked:
Data Flow:
Capture a -> b: Valueacaptured intobAlias a -> b:baliasesaAssign a -> b: Direct assignmentFreeze value: Make value immutable
Mutate value: Direct mutationMutateTransitive value: Transitive mutationMutateConditionally value: Conditional mutation
Render place: Used in JSX/render contextImpure place: Contains impure value (Date.now(), ref.current)
InferReactivePlaces
File:src/Inference/InferReactivePlaces.ts
Marks which places are reactive (need memoization).
Reactive categories:
- Component props
- Hook return values
- Values derived from reactive values
- Values used in JSX (render context)
Reactive Scope Passes
InferReactiveScopeVariables
File:src/ReactiveScopes/InferReactiveScopeVariables.ts
Groups instructions that should invalidate together.
Algorithm:
- Build value dependency graph
- Find strongly connected components
- Create scope boundaries
- Compute scope dependencies
Scope Alignment Passes
AlignMethodCallScopes
File:src/ReactiveScopes/AlignMethodCallScopes.ts
Aligns method call scopes with their receivers.
AlignObjectMethodScopes
File:src/ReactiveScopes/AlignObjectMethodScopes.ts
Aligns object method definitions to scope boundaries.
AlignReactiveScopesToBlockScopesHIR
File:src/ReactiveScopes/AlignReactiveScopesToBlockScopesHIR.ts
Ensures reactive scopes respect control flow boundaries.
Scope Merging
MergeOverlappingReactiveScopesHIR
File:src/HIR/MergeOverlappingReactiveScopesHIR.ts
Merges scopes with overlapping ranges.
Example:
MergeReactiveScopesThatInvalidateTogether
File:src/ReactiveScopes/MergeReactiveScopesThatInvalidateTogether.ts
Merges scopes that always invalidate together.
Scope Pruning
FlattenReactiveLoopsHIR
File:src/ReactiveScopes/FlattenReactiveLoopsHIR.ts
Prunes reactive scopes inside loops (can’t memoize loop iterations).
FlattenScopesWithHooksOrUseHIR
File:src/ReactiveScopes/FlattenScopesWithHooksOrUseHIR.ts
Removes scopes containing hook calls (hooks can’t be conditional).
PruneNonEscapingScopes
File:src/ReactiveScopes/PruneNonEscapingScopes.ts
Removes scopes for values that don’t escape the function.
PruneNonReactiveDependencies
File:src/ReactiveScopes/PruneNonReactiveDependencies.ts
Removes non-reactive dependencies from scope deps.
PruneAlwaysInvalidatingScopes
File:src/ReactiveScopes/PruneAlwaysInvalidatingScopes.ts
Removes scopes that always recompute.
Dependency Optimization
PropagateScopeDependenciesHIR
File:src/HIR/PropagateScopeDependenciesHIR.ts
Computes minimal precise dependencies for scopes.
Example:
Optional Transformations
Drop Manual Memoization
File:src/Inference/DropManualMemoization.tsCondition:
!enablePreserveExistingManualUseMemo
Removes manual useMemo/useCallback calls.
Transform Fire
File:src/Transform/TransformFire.tsFlag:
enableFire
Transforms fire() calls for effect callbacks.
Lower Context Access
File:src/Optimization/LowerContextAccess.tsFlag:
lowerContextAccess
Optimizes React context access with inline selectors.
Outline JSX
File:src/Optimization/OutlineJsx.tsFlag:
enableJsxOutlining
Extracts static JSX into separate components.
Outline Functions
File:src/Optimization/OutlineFunctions.tsFlag:
enableFunctionOutlining
Extracts pure function expressions to module scope.
Optimize for SSR
File:src/Optimization/OptimizeForSSR.tsCondition:
outputMode === 'ssr'
Applies server-side rendering optimizations.
Inline JSX Transform
File:src/Optimization/InlineJsxTransform.tsFlag:
inlineJsxTransform
Inlines JSX as object literals instead of runtime calls.
Code Generation Passes
Rename Variables
File:src/ReactiveScopes/RenameVariables.ts
Ensures unique variable names in output.
Promote Used Temporaries
File:src/ReactiveScopes/PromoteUsedTemporaries.ts
Promotes compiler temporaries to named variables when referenced across scopes.
Codegen Reactive Function
File:src/ReactiveScopes/CodegenReactiveFunction.ts
Generates final JavaScript with memoization:
Pass Ordering
Passes run in a specific order to ensure correctness:- Lower → Convert to HIR
- EnterSSA → SSA form
- Type/Effect Inference → Understand data flow
- Scope Inference → Find memoization boundaries
- Scope Optimization → Prune and merge scopes
- Codegen → Generate output
Performance Impact
Pass Complexity
| Pass | Time Complexity | Notes |
|---|---|---|
| Lower | O(n) | Linear in AST size |
| SSA | O(n + e) | CFG edges |
| Type Inference | O(n²) | Worst case (unification) |
| Effect Inference | O(n·d) | d = avg dependencies |
| Scope Inference | O(n·s) | s = scope count |
| Codegen | O(n + s) | Linear |
Typical Times
- Small component (less than 100 LOC): 1-2ms
- Medium component (100-500 LOC): 2-5ms
- Large component (500+ LOC): 5-20ms
Next Steps
Architecture
Understand the full pipeline
HIR
Learn about the IR
Configuration
Enable/disable passes
Contributing
Contribute optimizations