From 9705ec03865333d0a07dcf0dbc30fbaf80564e44 Mon Sep 17 00:00:00 2001
From: SkyZeroZx <73321943+SkyZeroZx@users.noreply.github.com>
Date: Wed, 4 Mar 2026 14:35:42 -0500
Subject: [PATCH] docs: add docs for `IdleService` and customization for the
`@defer idle` trigger
---
.../content/guide/incremental-hydration.md | 9 ++++-
adev/src/content/guide/templates/defer.md | 35 ++++++++++++++++++-
packages/core/src/defer/idle_service.ts | 5 +++
3 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/adev/src/content/guide/incremental-hydration.md b/adev/src/content/guide/incremental-hydration.md
index a4f5606bd2d..9a61c2b01c6 100644
--- a/adev/src/content/guide/incremental-hydration.md
+++ b/adev/src/content/guide/incremental-hydration.md
@@ -49,7 +49,7 @@ The available triggers are as follows:
| Trigger | Description |
| --------------------------------------------------- | ---------------------------------------------------------------------- |
-| [`hydrate on idle`](#hydrate-on-idle) | Triggers when the browser is idle. |
+| [`hydrate on idle`](#hydrate-on-idle) | Triggers when the browser is idle. Supports an optional timeout. |
| [`hydrate on viewport`](#hydrate-on-viewport) | Triggers when specified content enters the viewport |
| [`hydrate on interaction`](#hydrate-on-interaction) | Triggers when the user interacts with specified element |
| [`hydrate on hover`](#hydrate-on-hover) | Triggers when the mouse hovers over specified area |
@@ -60,12 +60,19 @@ The available triggers are as follows:
The `hydrate on idle` trigger loads the deferrable view's dependencies and hydrates the content once the browser has reached an idle state, based on `requestIdleCallback`.
+You can optionally specify a timeout in milliseconds that is passed to [`requestIdleCallback`](https://developer.mozilla.org/docs/Web/API/Window/requestIdleCallback). If the browser doesn't schedule the callback soon enough, the work will run no later than the specified timeout.
+
```angular-html
@defer (hydrate on idle) {
} @placeholder {
Large component placeholder
}
+
+
+@defer (hydrate on idle(500)) {
+
+}
```
#### `hydrate on viewport`
diff --git a/adev/src/content/guide/templates/defer.md b/adev/src/content/guide/templates/defer.md
index cee24edc06f..c7742247c93 100644
--- a/adev/src/content/guide/templates/defer.md
+++ b/adev/src/content/guide/templates/defer.md
@@ -134,7 +134,7 @@ The available triggers are as follows:
| Trigger | Description |
| ----------------------------- | ---------------------------------------------------------------------- |
-| [`idle`](#idle) | Triggers when the browser is idle. |
+| [`idle`](#idle) | Triggers when the browser is idle. Supports an optional timeout. |
| [`viewport`](#viewport) | Triggers when specified content enters the viewport |
| [`interaction`](#interaction) | Triggers when the user interacts with specified element |
| [`hover`](#hover) | Triggers when the mouse hovers over specified area |
@@ -145,6 +145,8 @@ The available triggers are as follows:
The `idle` trigger loads the deferred content once the browser has reached an idle state, based on requestIdleCallback. This is the default behavior with a defer block.
+You can optionally specify a timeout in milliseconds that is passed to [`requestIdleCallback`](https://developer.mozilla.org/docs/Web/API/Window/requestIdleCallback). If the browser doesn't schedule the callback soon enough, the work will run no later than the specified timeout.
+
```angular-html
@defer {
@@ -152,6 +154,32 @@ The `idle` trigger loads the deferred content once the browser has reached an id
} @placeholder {
Large component placeholder
}
+
+
+@defer (on idle(500)) {
+
+}
+```
+
+##### Customizing `idle` behavior
+
+You can customize the `idle` trigger by providing your own `IdleService` implementation and registering it with `provideIdleServiceWith` in your application's providers.
+
+```ts
+@Injectable({providedIn: 'root'})
+class CustomIdleService implements IdleService {
+ requestOnIdle(callback: (deadline?: IdleDeadline) => void, options?: IdleRequestOptions) {
+ // Custom idle scheduling logic can be implemented here.
+ }
+
+ cancelOnIdle(id: number) {
+ // Implement custom idle cancellation here.
+ }
+}
+
+bootstrapApplication(App, {
+ providers: [provideIdleServiceWith(CustomIdleService)],
+});
```
#### `viewport`
@@ -297,6 +325,11 @@ In the example below, the prefetching starts when a browser becomes idle and the
} @placeholder {
Large component placeholder
}
+
+
+@defer (on interaction; prefetch on idle(500)) {
+
+}
```
## Testing `@defer` blocks
diff --git a/packages/core/src/defer/idle_service.ts b/packages/core/src/defer/idle_service.ts
index 351b30163e5..116d9f76022 100644
--- a/packages/core/src/defer/idle_service.ts
+++ b/packages/core/src/defer/idle_service.ts
@@ -33,6 +33,9 @@ const _cancelIdleCallback = () =>
* Service which configures custom 'on idle' behavior for Angular features like `@defer`.
*
* @publicApi
+ *
+ * @see [Customizing `idle` behavior](guide/templates/defer#customizing-idle-behavior)
+ *
*/
export interface IdleService {
/**
@@ -60,6 +63,8 @@ export const IDLE_SERVICE = new InjectionToken(ngDevMode ? 'IDLE_SE
* must implement the `IdleService` interface.
*
* @publicApi
+ *
+ * @see [Customizing `idle` behavior](guide/templates/defer#customizing-idle-behavior)
*/
export function provideIdleServiceWith(
useExisting: AbstractType | InjectionToken,