⭐Angular 17 Features ⭐
Sandeep Balachandran
Posted on May 23, 2024
Hey there,
Version 17.0.0 is here and it has some great updates for Angular developers everywhere. 🎉🎉
TL;DR 🙌
✅ Future-looking identity
✅ Built-in control flow
✅ Deferrable views
✅ Revamped hybrid rendering experience
✅ New @angular/ssr package
✅ New lifecycle hooks
✅ Vite and esbuild the default for new projects
✅ Dependency injection debugging in DevTools
✅ Improving Developer Experience
How to update to version 17
Visit update.angular.io for detailed information and guidance. To have the best update experience,
Update to 17
ng update @angular/cli @angular/core
In order to update your global angular,
npm i -g @angular/cli
What’s in this release?
✅ Future-looking identity
- With Angular 17, developers can now access an updated documentation platform hosted on angular.dev
- The new website has new structure, new guides, improved content, and built a platform for an interactive learning journey that will let you learn Angular and the Angular CLI at your own pace, directly in the browser.
- Currently it is in beta preview and planning to make it the default website for Angular in v18.
- Read more about it here 👉 Blog post
✅ Built-in control flow
- The built-in control flow is available in v17 under developer preview today!
- Angular 17 introduces a new block template syntax, enhancing the developer experience by offering powerful features
- A new block template syntax that gives you powerful features with simple, declarative APIs are released
- Under the hood, the Angular compiler transforms the syntax to efficient JavaScript instructions that could perform control flow, lazy loading, and more.
- The built-in control flow enables:
- More ergonomic syntax that is closer to JavaScript, thus more intuitive requiring fewer documentation lookups
- Better type checking thanks to more optimal type narrowing
- It’s a concept that primarily exists at build-time, which reduces the runtime footprint (making it “disappearing”) which could drop your bundle size by up to 30 kilobytes and further improve your Core Web Vital scores
- It is automatically available in your templates without additional imports
✅ Conditional statements
<div *ngIf="loggedIn; else anonymousUser">
The user is logged in
</div>
<ng-template #anonymousUser>
The user is not logged in
</ng-template>
With the built-in if statement, this condition will look like:
@if (loggedIn) {
The user is logged in
} @else {
The user is not logged in
}
- Being able to provide the content for @else directly is a major simplification compared to the else clause of the legacy *ngIf alternative.
- The current control flow also makes it trivial to have @else if, which historically has been impossible.
- The improved ergonomics is even more visible with *ngSwitch:
<div [ngSwitch]="accessLevel">
<admin-dashboard *ngSwitchCase="admin"/>
<moderator-dashboard *ngSwitchCase="moderator"/>
<user-dashboard *ngSwitchDefault/>
</div>
which with the built-in control flow turns into:
@switch (accessLevel) {
@case ('admin') { <admin-dashboard/> }
@case ('moderator') { <moderator-dashboard/> }
@default { <user-dashboard/> }
}
- The new control flow enables significantly better type-narrowing in the individual branches in @switch which is not possible in *ngSwitch.
✅ Built-in for loop
@for (user of users; track user.id) {
{{ user.name }}
} @empty {
Empty list of users
}
- We often see performance problems in apps due to the lack of trackBy function in *ngFor.
- A few differences in @for are that track is mandatory to ensure fast diffing performance.
- In addition, it’s way easier to use since it’s just an expression rather than a method in the component’s class.
- The built-in @for loop also has a shortcut for collections with zero items via an optional @empty block.
- The @for statement uses a new diffing algorithm and has more optimal implementation compared to *ngFor, which makes it up to 90% faster runtime for community framework benchmarks!
✅ Deferrable views
- Angular 17 introduces a concept known as deferrable views or @defer blocks
- Deferrable views are available in developer preview in v17
- Deferrable views bring performance and developer experience to the next level because they enable declarative and powerful deferred loading with unprecedented ergonomics.
@defer (on viewport) {
<comment-list/>
} @loading {
Loading…
} @error {
Loading failed :(
} @placeholder {
<img src="comments-placeholder.png">
}
- There’s a ton of complexity under the hood that Angular manages for you.
-
Deferrable views offer a few more triggers:
- on idle — lazily load the block when the browser is not doing any heavy lifting
- on immediate — start lazily loading automatically, without blocking the browser
- on timer(
- on viewport and on viewport() — viewport also allows to specify a reference for an anchor element. When the anchor element is visible, Angular will lazily load the component and render it
- on interaction and on interaction() — enables you to initiate lazy loading when the user interacts with a particular element
- on hover and on hover() — triggers lazy loading when the user hovers an element
- when — enables you to specify your own condition via a boolean expression
Deferrable views also provide the ability to prefetch the dependencies ahead of rendering them.
Adding prefetching is as simple as adding a prefetch statement to the defer block and supports all the same triggers.
@defer (on viewport; prefetch on idle) {
<comment-list />
}
✅ Revamped hybrid rendering experience
- Angular 17 brings a revitalized hybrid rendering experience, offering robust server-side rendering (SSR) and static site generation (SSG) support
✅ New @angular/ssr package
- Angular Universal repository is moved to the Angular CLI repository and made server-side rendering an even more integral part
- To add hybrid rendering support to your existing application run:
ng add @angular/ssr
✅ New lifecycle hooks
- 2 new life cycle hooks introduced in this release
- afterRender — register a callback to be invoked each time the application finishes rendering
- afterNextRender — register a callback to be invoked the next time the application finishes rendering
- Only the browser will invoke these hooks, which enables you to plug custom DOM logic safely directly inside your components.
✅ Vite and esbuild the default for new projects
- esbuild plus Vite powered build experience is enabled by default for all new applications
- Benefits
- A 67% improvement in build time.
- An 87% speed improvement with SSR and SSG.
- A lightweight and efficient build process.
✅ Dependency injection debugging in DevTools
brand new debugging APIs are introduced that allow us to plug into the framework’s runtime and inspect the injector tree.
-
Based on these APIs we built an inspection user interface that allows you to preview the:
- Dependencies of your components in the component inspector
- Injector tree and dependency resolution path
- Providers declared within the individual injectors
✅ Improving Developer Experience
Input value transforms
- A common pattern is having a component which receives a boolean input.
- This, however, sets constraints on how you can pass a value to such a component.
- For example if we have the following definition of an Expander component:
@Component({
standalone: true,
selector: 'my-expander',
template: `…`
})
export class Expander {
@Input() expanded: boolean = false;
}
- and we try to use it as
<my-expander expanded/>
- You’ll get an error that “string is not assignable to boolean”.
- Input value transforms allow you to fix this by configuring the input decorator:
@Component({
standalone: true,
selector: 'my-expander',
template: `…`
})
export class Expander {
@Input({ transform: booleanAttribute }) expanded: boolean = false;
}
Style and styleUrls as strings
- Angular components support multiple stylesheets per component.
- However, the vast majority of cases when I want to style my components I create an array with a single element pointing to the inline styles or referencing an external stylesheet
- A new feature enables you to switch from *
@Component({
styles: [`
...
`]
})
@Component({
styleUrls: ['styles.css']
})
to the simpler and more logical
@Component({
styles:``
})
@Component({
styleUrl: 'styles.css'
})
For more let us hear it from the creators
Credits : Official Announcement 😄
Changelog : Repository
Posted on May 23, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.