myHotTake

Angular Route Reuse Strategy: Boost Speed or Waste Memory?

If this analogy helps you understand Angular’s route reuse strategies, give it a like or share—it might help someone else too! Alright, let’s dive in.


I’m a traveler with a suitcase, moving through a big airport. Each gate represents a route, and my flight ticket represents the component tied to that route. Every time I go to a new gate, I have to unpack and repack my suitcase. It takes time, it’s tiring, and honestly, it’s inefficient when I might just be coming back to the same gate later.

Now, here’s where the route reuse strategy comes in. Instead of unpacking and repacking my suitcase every time, I decide to leave my bag at certain gates I frequently visit. When I return, it’s already there—no wasted effort! This is like Angular deciding to hold onto the component state and DOM of a route rather than destroying and recreating it.

But there’s a catch: if I leave my bag at every gate I pass, the airport quickly runs out of space. That’s why I need a clear strategy—only leaving my bag at gates I know I’ll come back to soon. Similarly, Angular allows me to control when and where components should be reused, balancing performance gains with memory costs.

When done thoughtfully, this strategy speeds things up. My journey through the airport (or the user’s navigation in the app) becomes much smoother. But if I get careless, leaving too much baggage everywhere, it might slow things down because the system has to manage all that leftover luggage.

So, route reuse in Angular is about smart packing: deciding what to keep and where, ensuring both speed and efficiency. Just like a good traveler knows how to pack light and move fast, a good developer uses route reuse to make the app fly. ✈️


Reusing Routes in Angular: The Basics

By default, Angular destroys and recreates components whenever a user navigates between routes. To implement a route reuse strategy, we can take control using the RouteReuseStrategy interface.

Here’s an example of a custom route reuse strategy:

import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router';

export class CustomReuseStrategy implements RouteReuseStrategy {
  private storedRoutes = new Map<string, DetachedRouteHandle>();

  // Decide if a route should be stored
  shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return route.routeConfig && route.routeConfig.path === 'frequent-route';
  }

  // Store the detached route
  store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
    if (route.routeConfig) {
      this.storedRoutes.set(route.routeConfig.path!, handle);
    }
  }

  // Decide if a route should be reused
  shouldAttach(route: ActivatedRouteSnapshot): boolean {
    return !!route.routeConfig && this.storedRoutes.has(route.routeConfig.path!);
  }

  // Retrieve the stored route
  retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
    return route.routeConfig ? this.storedRoutes.get(route.routeConfig.path!) || null : null;
  }

  // Decide if a route should be reloaded
  shouldReuseRoute(
    future: ActivatedRouteSnapshot,
    curr: ActivatedRouteSnapshot
  ): boolean {
    return future.routeConfig === curr.routeConfig;
  }
}

Using the Custom Route Reuse Strategy

Once the custom strategy is defined, Angular needs to be told to use it. This is done in the AppModule:

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { CustomReuseStrategy } from './custom-reuse-strategy';

@NgModule({
  declarations: [],
  imports: [RouterModule.forRoot(routes)],
  providers: [
    { provide: RouteReuseStrategy, useClass: CustomReuseStrategy }
  ],
})
export class AppModule {}

Key Elements in the Code:

  1. shouldDetach: Determines if the current route should be saved for reuse.
  2. store: Saves the route along with its detached state (essentially the “suitcase” we’re leaving behind).
  3. shouldAttach: Checks if there’s a previously stored route that can be reattached.
  4. retrieve: Retrieves the stored route’s handle to reattach it.
  5. shouldReuseRoute: Decides if a route should be reused based on the future and current route configurations.

Key Takeaways / Final Thoughts

  1. Performance Benefits: Route reuse prevents unnecessary component destruction and recreation, making the app faster.
  2. Memory Trade-Offs: Overuse of reuse strategies can lead to increased memory usage. Choose carefully which routes to reuse.
  3. Customization: Angular’s RouteReuseStrategy allows full control over route reuse, but it requires careful implementation to avoid bugs or excessive complexity.
  4. Best Practices: Test extensively to ensure the reused state behaves as expected across different user interactions.