Skip to content

Conversation

@atscott
Copy link
Contributor

@atscott atscott commented Dec 10, 2025

This commit introduces a new feature to automatically destroy EnvironmentInjectors associated with routes that are no longer active or stored. This helps in managing memory by releasing resources held by unused injectors.

Key changes:

  • Added shouldDestroyInjector and retrieveStoredRouteHandles to RouteReuseStrategy.
  • Introduced withExperimentalAutoCleanupInjectors provider function to opt-in to this feature.
  • Implemented a "mark and sweep" algorithm to identify and destroy unused injectors.
  • Added a dev mode warning if the strategy implements destruction methods but the feature is not enabled.
  • Added integration tests to verify the behavior.

This commit also destroyDetachedRouteHandle, a standalone function that allows developers to explicitly destroy the component associated with a DetachedRouteHandle.

We chose to implement this as a standalone function rather than adding a destroy() method to the DetachedRouteHandle type to avoid breaking changes. Currently, DetachedRouteHandle is defined as {}, and many applications mock it as such. Adding a required method to the interface would break these existing tests and usages.

By using a standalone function, we can safely cast the handle to its internal type and invoke destruction without altering the public contract of the handle itself.

This feature is particularly useful for RouteReuseStrategy implementations that need to drop stored handles and ensure the associated components are properly cleaned up to prevent memory leaks.

resolves #27290
resolves #37095
resolves #15873

@angular-robot angular-robot bot added detected: feature PR contains a feature commit area: router labels Dec 10, 2025
@ngbot ngbot bot added this to the Backlog milestone Dec 10, 2025
@atscott atscott force-pushed the routerInjectorCleanup branch from 454e237 to d522cf7 Compare December 10, 2025 22:17
@atscott atscott force-pushed the routerInjectorCleanup branch from d522cf7 to 14415ed Compare December 10, 2025 22:35
@atscott atscott added the target: minor This PR is targeted for the next minor release label Dec 10, 2025
This commit introduces a new feature to automatically destroy `EnvironmentInjector`s associated with routes that are no longer active or stored. This helps in managing memory by releasing resources held by unused injectors.

Key changes:
- Added `shouldDestroyInjector` and `retrieveStoredRouteHandles` to `RouteReuseStrategy`.
- Introduced `withExperimentalAutoCleanupInjectors` provider function to opt-in to this feature.
- Implemented a "mark and sweep" algorithm to identify and destroy unused injectors.
- Added a dev mode warning if the strategy implements destruction methods but the feature is not enabled.
- Added integration tests to verify the behavior.

This commit also `destroyDetachedRouteHandle`, a standalone function that allows developers to explicitly destroy the component associated with a `DetachedRouteHandle`.

We chose to implement this as a standalone function rather than adding a `destroy()` method to the `DetachedRouteHandle` type to avoid breaking changes. Currently, `DetachedRouteHandle` is defined as `{}`, and many applications mock it as such. Adding a required method to the interface would break these existing tests and usages.

By using a standalone function, we can safely cast the handle to its internal type and invoke destruction without altering the public contract of the handle itself.

This feature is particularly useful for `RouteReuseStrategy` implementations that need to drop stored handles and ensure the associated components are properly cleaned up to prevent memory leaks.

resolves angular#27290
resolves angular#37095
@atscott atscott force-pushed the routerInjectorCleanup branch from 14415ed to 09a537c Compare December 10, 2025 22:52
@github-actions
Copy link

github-actions bot commented Dec 10, 2025

Deployed adev-preview for 726fc25 to: https://ng-dev-previews-fw--pr-angular-angular-65991-adev-prev-tzo73rw0.web.app

Note: As new commits are pushed to this pull request, this link is updated after the preview is rebuilt.

Comment on lines +40 to +41
* This function should be used when a `RouteReuseStrategy` decides to drop a stored handle
* and wants to ensure that the component is destroyed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we can enforce that somehow (avoid calling this function in other places in the code).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can call this function from anywhere at any time. This is not called automatically by the router but ad-hoc if/when the user decides to they don't need the handle anymore.

@pullapprove pullapprove bot requested a review from AndrewKushnir December 13, 2025 02:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

adev: preview area: router detected: feature PR contains a feature commit target: minor This PR is targeted for the next minor release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Angular Module instance never get destroyed Refine RouteReuseStrategy Feature: provide a way to dispose DetachedRouteHandle

5 participants