diff --git a/docs/component/_category_.yml b/docs/component/_category_.yml index 12a3022..b7b0e02 100644 --- a/docs/component/_category_.yml +++ b/docs/component/_category_.yml @@ -2,4 +2,4 @@ label: Component position: 3 link: type: generated-index -className: updated \ No newline at end of file +className: new \ No newline at end of file diff --git a/docs/component/change-detection.md b/docs/component/change-detection.md new file mode 100644 index 0000000..7657653 --- /dev/null +++ b/docs/component/change-detection.md @@ -0,0 +1,64 @@ +--- +sidebar_position: 4 +sidebar_class_name: new +--- +# Change detection + +Change detection is a core concept in Angular that ensures the UI stays in sync with the application state. This guide explores best practices for managing change detection effectively, including strategies for optimizing performance and leveraging Angular's built-in mechanisms. + +## General guidelines + +**Consider** using `ChangeDetectionStrategy.OnPush` for every components. +- ❌ unspecified change detection strategy +- ❌ `changeDetection: ChangeDetectionStrategy.Default` +- ✅ `changeDetection: ChangeDetectionStrategy.OnPush` + +:::info Why? +The main reason is sustainability. Angular is heading towards better reactivity with signals and Zoneless application, and using `OnPush` now will make migration to future major releases easier. + +In addition, `OnPush` strategy improves performances by reducing the number of change detection cycles, which is particularly interesting for large projects. +::: + +:::tip +You can set the default change detection strategy to `OnPush` in your `angular.json` file for components generated with Angular CLI. +::: + +**Do** rely on reactive primitives to trigger change detection. + +- ✅ [Signals](../reactivity#signals) - reading a signal in a template registers it for updates, and calling `set()` or `update()` marks the view dirty. +- ✅ [Async Pipe](../reactivity#managing-subscriptions) - it subscribes to an Observable and triggers view checks on each emission. +- ✅ Event handlers, e.g. `(click)` or `(keydown)`. +- ✅ Input property changes from parent to child components. +- ❌ Timers, e.g. `setTimeout()` or `setInterval()`. +- ❌ HTTP requests + +:::tip +As a last resort, you can use `markForCheck()` method from `ChangeDetectorRef` to manually trigger change detection. +::: + +See [Reactivity](../reactivity.md) for more details. + +## Zoneless + +Zoneless mode represents a major shift in Angular’s change detection strategy. Historically, Angular relied on Zone.js, a patching library that intercepted asynchronous tasks—timers, promises, events—to automatically trigger UI updates. With zoneless, this implicit mechanism is gone. Angular no longer monitors every async operation; instead, updates happen only when the framework knows something changed. + +**Consider** using [Zoneless](https://v21.angular.dev/guide/zoneless). + +:::info Why? +Opting for Zoneless mode is a future-proof choice as Angular is moving towards this direction. While the performance enhancement is minimal (especially if you have already followed best practices, e.g. [`OnPush` change detection](../component/typescript-class#change-detection)), it can improve developer experience by providing clearer stack traces. Additionally, it'll help reduce bundle size and startup time. +::: + +:::tip +To migrate existing code to Zoneless mode, check for legacy code using `NgZone` or relying on implicit change detection after timers, HTTP calls, or event handlers. The most encountered problem is a piece of UI that does not reflect a state change until you interact with it. If state changes but the DOM stays stale, you can use debugging tools or logs to confirmand reactive patterns mentioned above to fix it. +::: + +:::warning Exceptions +When using third-party libraries that depend on `zone.js`, you may need to keep zone-based change detection enabled. Some libraries or tools might not function correctly without it, so evaluate compatibility before switching to Zoneless mode. +::: + +### Testing + +**Do** provide zoneless change detection in tests. +- ✅ `provideZonelessChangeDetection()` in `TestBed.configureTestingModule()` +- ❌ `fixture.detectChanges()` + diff --git a/docs/component/reusability.md b/docs/component/reusability.md index 69d6d96..ea94d8a 100644 --- a/docs/component/reusability.md +++ b/docs/component/reusability.md @@ -1,6 +1,6 @@ --- draft: true -sidebar_position: 4 +sidebar_position: 5 --- # Reusability - seperation of concern (the art of creating reusable components) diff --git a/docs/component/typescript-class.md b/docs/component/typescript-class.md index 81b0fe1..354edae 100644 --- a/docs/component/typescript-class.md +++ b/docs/component/typescript-class.md @@ -94,25 +94,6 @@ You can run [schematic migrations](https://v21.angular.dev/reference/migrations) - ❌ `selected = input(false)` and `selectedChange = output()` - ✅ `selected = model(false)` -## Change detection - -**Consider** using `ChangeDetectionStrategy.OnPush` for every components. -- ❌ unspecified change detection strategy -- ❌ `changeDetection: ChangeDetectionStrategy.Default` -- ✅ `changeDetection: ChangeDetectionStrategy.OnPush` - -:::info Why? -The main reason is sustainability. Angular is heading towards better reactivity with signals and Zoneless application, and using `OnPush` now will make migration to future major releases easier. - -In addition, `OnPush` strategy improves performances by reducing the number of change detection cycles, which is particularly interesting for large projects. -::: - -:::tip -You can set the default change detection strategy to `OnPush` in your `angular.json` file for components generated with Angular CLI. -::: - -More info about change detection in [Reactivity](../reactivity.md). - ## Lifecycle **Avoid** misusing or overusing component lifecycle hooks. diff --git a/docs/general/configuration.md b/docs/general/configuration.md index f298024..3d2564f 100644 --- a/docs/general/configuration.md +++ b/docs/general/configuration.md @@ -18,16 +18,6 @@ Standalone components are self-contained which is much easier to manage, and rem You can run the [schematic migration](https://v21.angular.dev/reference/migrations/standalone) to automatically convert your project to standalone. ::: -**Consider** using [Zoneless](https://v21.angular.dev/guide/zoneless). - -:::info Why? -Opting for Zoneless mode is a future-proof choice as Angular is moving towards this direction. While the performance impact is minimal (especially if you have already followed best practices, e.g. [`OnPush` change detection](../component/typescript-class#change-detection)), it can improve developer experience by providing clearer stack traces. Additionally, it'll help reduce bundle size and startup time. -::: - -:::warning Exceptions -When using third-party libraries that depend on `zone.js`, you may need to keep zone-based change detection enabled. Some libraries or tools might not function correctly without it, so evaluate compatibility before switching to Zoneless mode. -::: - ## Git **Do** commit `package.json` and `package-lock.json` files. diff --git a/docs/reactivity.md b/docs/reactivity.md index 5bd6819..86160b6 100644 --- a/docs/reactivity.md +++ b/docs/reactivity.md @@ -153,6 +153,14 @@ Since these new tools will most likely become the future of Angular, and that th **Consider** using [signals](#signals) instead of RxJs `BehaviorSubject`. +### Interoperability with signals + +**Do** use `toSignal()` to convert an Observable to a Signal. + +:::tip +You can combine Signals and RxJS when needed. Convert streams to signals with `toSignal()` for unified template usage while keeping Observables for complex async flows. +::: + ### Managing subscriptions **Do** unsubcribe from observables.