<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jarosław Żołnowski</title>
    <description>The latest articles on DEV Community by Jarosław Żołnowski (@jzolnowski).</description>
    <link>https://dev.to/jzolnowski</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1574356%2F2c2de1d0-3004-49c3-913f-2c4b8c194f23.jpg</url>
      <title>DEV Community: Jarosław Żołnowski</title>
      <link>https://dev.to/jzolnowski</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jzolnowski"/>
    <language>en</language>
    <item>
      <title>What's New in Angular v19?</title>
      <dc:creator>Jarosław Żołnowski</dc:creator>
      <pubDate>Mon, 30 Dec 2024 12:19:22 +0000</pubDate>
      <link>https://dev.to/jzolnowski/angular-v19-a-game-changing-release-21dn</link>
      <guid>https://dev.to/jzolnowski/angular-v19-a-game-changing-release-21dn</guid>
      <description>&lt;p&gt;Angular v19 is here, and it’s packed with powerful features and enhancements to make building high-performance web apps even easier. With this release, developers can look forward to improvements that enhance developer experience, boost app performance, and simplify APIs to make development faster and more efficient. Let’s explore what Angular v19 brings to the table.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Keeping Things in Sync with &lt;code&gt;linkedSignal&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;One of the standout features in Angular v19 is the introduction of &lt;code&gt;linkedSignals&lt;/code&gt;. This new reactive primitive ensures multiple signals stay in sync, making it perfect for maintaining derived states that depend on other signals.&lt;/p&gt;

&lt;p&gt;Here's a quick example: say you have a list of users and want to keep the selected user highlighted even when the list changes. With &lt;code&gt;linkedSignal&lt;/code&gt;, you can write code that automatically adjusts the selection behind the scenes, keeping things clean and organized.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;linkedSignal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserSelectionComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;availableUsers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nx"&gt;selectedUserId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;linkedSignal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;availableUsers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;computation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;previous&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;previous&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;previous&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;previous&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, &lt;code&gt;linkedSignal&lt;/code&gt; recalculates the selected user ID whenever the list of available users changes, reducing complexity in state management.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Streamlined Data Fetching with the &lt;code&gt;resource&lt;/code&gt; API&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Fetching data just got easier with the new &lt;code&gt;resource&lt;/code&gt; API. It simplifies async data handling by combining loaders, request tracking, and reactivity. This means less code for you and cleaner components that focus on what matters.&lt;/p&gt;

&lt;p&gt;Here’s how you can use &lt;code&gt;resource&lt;/code&gt; to fetch and manage user profile data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user_1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nx"&gt;userDetails&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;abortSignal&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`https://api.example.com/users/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;abortSignal&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;UserDetails&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;userDetails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Access user details&lt;/span&gt;
&lt;span class="nx"&gt;userDetails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Check loading state&lt;/span&gt;
&lt;span class="nx"&gt;userDetails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Handle errors&lt;/span&gt;

&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nf"&gt;updateUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userDetails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nf"&gt;reloadProfile&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userDetails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reload&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think of it like having a personal data assistant. You tell it what data you need, and it handles the whole process, letting you know when it's loading, if there are any errors, and of course, providing the data itself.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Faster Rendering with Incremental Hydration&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Incremental Hydration is a game-changer for server-side rendered (SSR) applications. Instead of hydrating the entire app at once, Angular now hydrates UI sections only when needed, reducing the initial JavaScript payload and processing time.&lt;/p&gt;

&lt;p&gt;To enable this, you just need to tweak your app's configuration a bit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;provideClientHydration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;withIncrementalHydration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ApplicationConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/platform-browser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;appConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ApplicationConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;provideClientHydration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;withIncrementalHydration&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can control exactly which parts get hydrated using &lt;a href="https://angular.dev/guide/incremental-hydration#controlling-hydration-of-content-with-triggers" rel="noopener noreferrer"&gt;hydration triggers&lt;/a&gt; with the &lt;code&gt;@defer&lt;/code&gt; directive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@defer (hydrate on hover) {
  &lt;span class="nt"&gt;&amp;lt;app-hydrated-content&amp;gt;&amp;lt;/app-hydrated-content&amp;gt;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, the  component will only load when hovered. This enables fine-grained hydration of components, ensuring better performance and resource usage.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Flexible Render Modes with &lt;code&gt;ServerRoute&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Ever wanted to choose how different parts of your app render? Angular v19 introduces &lt;code&gt;ServerRoute&lt;/code&gt; interface, giving you the power to decide whether a route should be rendered on the server, pre-rendered in the background, or handled by the client.&lt;/p&gt;

&lt;p&gt;For example, you might want your login page to be server-side rendered for security reasons, while your dashboard could be client-side rendered for a more interactive experience:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;serverRouteConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ServerRoute&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RenderMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Server&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RenderMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Client&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RenderMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Prerender&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One cool thing about &lt;code&gt;ServerRoute&lt;/code&gt; is that it lets you dynamically resolve route parameters during pre-rendering. This means you can use your Angular services to fetch data and customize the content before it's even sent to the browser.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ServerRoute&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/platform-server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;inject&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;serverRoutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ServerRoute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;prerender&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;getPrerenderPaths&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userIds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getUserIds&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;userIds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;getPrerenderPaths&lt;/code&gt; function executes in an injection context, allowing to use Angular services to fetch and resolve user id dynamically.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Instant Feedback with Enhanced HMR&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Angular v19 takes Hot Module Replacement (HMR) to the next level. Before, if you tweaked some CSS or changed your template, the whole app would have to rebuild and refresh in the browser. It worked, sure, but this process often interrupted the developer’s flow and reset the application state, like if you were filling out a form and suddenly...everything's gone.. With the enhanced HMR in Angular v19, these interruptions are a thing of the past.&lt;/p&gt;

&lt;p&gt;Now, those annoying interruptions are history! With the new and improved HMR in v19, when you change your component's styles or template and hit save, Angular is smart enough to just compile the parts you changed. It then sends those updates to the browser and patches the running app without a full page refresh. This means you see your changes instantly.&lt;/p&gt;

&lt;p&gt;Imagine you're working on a product page and need to tweak the style of a button while maintaining the current application state. With HMR, we can change the button’s styles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.button-primary&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#007bff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;Updated&lt;/span&gt; &lt;span class="err"&gt;color&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And...see changes instantly without a full page reload or losing form input, scroll position, or other dynamic states.&lt;/p&gt;

&lt;p&gt;The best part? Hot module replacement for styles is enabled by default in v19, so you get it right out of the box.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Enhanced Security with Automatic Content Security Policy&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Security is a big deal, and Angular v19 is making it easier to keep your apps safe with a new feature called &lt;code&gt;AutoCSP&lt;/code&gt;. This is currently in developer preview, so it's still being refined, but it's a really cool step forward. &lt;code&gt;AutoCSP&lt;/code&gt; automatically generates a hash-based Content Security Policy (CSP).&lt;/p&gt;

&lt;p&gt;Basically, a CSP acts as a security layer, specifying which resources a browser is allowed to load and execute. Each script in your app gets a unique "fingerprint" (a unique hash). The browser will only run a script if its fingerprint is on the CSP's "approved" list. This is a super effective way to stop attackers from injecting malicious scripts because they can't create the correct fingerprint for their sneaky code.&lt;/p&gt;

&lt;p&gt;To enable the &lt;code&gt;AutoCSP&lt;/code&gt; feature, we need to update the &lt;code&gt;angular.json&lt;/code&gt; configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"projects"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"my-angular-app"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"architect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"security"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"autoCSP"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you've done this, Angular takes care of the rest. During the build process, it automatically generates the CSP with the correct fingerprints for all your inline scripts in &lt;code&gt;index.html&lt;/code&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Standalone Components as the Default&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Angular v19 makes a big push towards simpler components. Remember those NgModules? Well, in many cases, you won't need them anymore! Standalone components are now the default way to create components. And for those who want to fully embrace the standalone way, there's a strict mode you can enable in your &lt;code&gt;tsconfig.json&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"angularCompilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"strictStandalone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures everything in your app is using the modern standalone approach, leading to a cleaner and more consistent project structure and lets you take full advantage of the latest Angular features.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Improved Theming with Angular Material&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;With the release of Angular v19, the Angular Material and CDK teams have taken a significant step forward by improving the theming API. It's now way easier to create and customize themes, building on the already awesome Material 3 framework. The new API not only streamlines theming but also provides developers with tools to make component-specific customizations more efficient and expressive. Say goodbye to repetitive code and hello to streamlined theming:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Making Themes Easier with mat.theme&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;In the past, creating a custom theme in Material required defining themes for each component separately. It worked, but it was often a lot of repetitive code. Now, with v19, there's a new &lt;code&gt;mat.theme&lt;/code&gt; mixin that lets you define your entire theme – colors, fonts, spacing – in one place.&lt;/p&gt;

&lt;p&gt;In earlier versions of Angular Material, creating a custom theme required defining themes for individual components using separate mixins. This approach, while powerful, often led to repetitive and verbose code. Angular v19 introduces the &lt;code&gt;mat.theme&lt;/code&gt; mixin, which allows developers to define custom themes using a single, unified declaration.&lt;/p&gt;

&lt;p&gt;Here’s an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@use&lt;/span&gt; &lt;span class="s1"&gt;'@angular/material'&lt;/span&gt; &lt;span class="nt"&gt;as&lt;/span&gt; &lt;span class="nt"&gt;mat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@include&lt;/span&gt; &lt;span class="nd"&gt;mat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nv"&gt;$color-palette&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="nv"&gt;$typography-config&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="nv"&gt;$density-config&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This single line of code sets up your entire theme - the definition of color palettes, typography, and density. The resulting theme is applied globally, reducing boilerplate and making theme management easier.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;More Ways to Customize Material 3&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Angular Material v19 also gives you more flexibility with colors and fonts. You can now create multiple themes for different parts of your app and even switch between them on the fly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@use&lt;/span&gt; &lt;span class="s1"&gt;'@angular/material'&lt;/span&gt; &lt;span class="nt"&gt;as&lt;/span&gt; &lt;span class="nt"&gt;mat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nv"&gt;$dark-theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define-theme&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;
  &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;primary&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$cyan-palette&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;secondary&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$amber-palette&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;theme-type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;typography&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define-typography&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;font-family&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Georgia, serif'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;density&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="nc"&gt;.dark-mode&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;@include&lt;/span&gt; &lt;span class="nd"&gt;mat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$dark-theme&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;Component-Specific Overrides&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;One of the coolest additions (at least from my perspective) is the ability to make targeted customizations for individual components using the new overrides API. This allows developers to tweak specific design tokens for components without altering the global theme.&lt;/p&gt;

&lt;p&gt;Let's say you want to change the background and divider color of a &lt;code&gt;mat-sidenav&lt;/code&gt; component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@include&lt;/span&gt; &lt;span class="nd"&gt;mat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sidenav-overrides&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;
  &lt;span class="s1"&gt;'content-background-color'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="no"&gt;lightblue&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'container-divider-color'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="no"&gt;darkgray&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lets you tweak specific components while still keeping a consistent overall look and feel.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Enhanced Drag &amp;amp; Drop with Mixed Orientation&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Angular's CDK now supports drag-and-drop in two dimensions, making it even more powerful for building interactive user interfaces. This opens the door for creating things like Kanban boards, grid layouts, or even creative layout editors, without the need for third-party libraries.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Support for Tab Reordering&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Angular v19 introduces support for tab reordering, enabling users to rearrange tabs dynamically. This feature enhances the user experience for applications with complex tab-based interfaces.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;New Time Picker Component&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Another addition is the brand new &lt;strong&gt;Time Picker Component&lt;/strong&gt;, which simplifies time selection in forms and input fields. The component is highly customizable, integrates seamlessly with Angular forms, and supports various formats. &lt;/p&gt;




&lt;h3&gt;
  
  
  Wrapping It Up
&lt;/h3&gt;

&lt;p&gt;Angular v19 is a big step forward, giving developers powerful tools to build apps faster and more secured. From reactive features to security improvements and simplified standalone defaults, Angular v19 is a release worth checking out. With support for advanced theming, dynamic prerendering, and productivity-enhancing tools like HMR, Angular continues to set the standard for front-end frameworks. So go ahead and start exploring the possibilities!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Say Goodbye to Long Relative Paths with tsconfig Aliases</title>
      <dc:creator>Jarosław Żołnowski</dc:creator>
      <pubDate>Sun, 24 Nov 2024 10:48:28 +0000</pubDate>
      <link>https://dev.to/jzolnowski/say-goodbye-to-long-relative-paths-with-tsconfig-aliases-20e3</link>
      <guid>https://dev.to/jzolnowski/say-goodbye-to-long-relative-paths-with-tsconfig-aliases-20e3</guid>
      <description>&lt;p&gt;Let’s be real - working with long relative paths can be a pain. Who hasn’t had to deal with something like this?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AuthService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../../services/auth.service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s messy, hard to read, and even harder to manage when your app grows. But here’s the good news: there’s a way to ditch those long paths and keep your code clean and readable. Enter &lt;strong&gt;tsconfig aliases&lt;/strong&gt;! 🎉  &lt;/p&gt;




&lt;h3&gt;
  
  
  What Are Aliases, and Why Should You Care?
&lt;/h3&gt;

&lt;p&gt;With &lt;strong&gt;tsconfig aliases&lt;/strong&gt;, you can replace those clunky relative paths with short, clean ones that look like below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AuthService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@services/auth.service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No more counting &lt;code&gt;../&lt;/code&gt; or getting lost in nested directories. Aliases make your imports:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Readable&lt;/strong&gt;: Short paths are easier to read and understand.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintainable&lt;/strong&gt;: Move files around without breaking half your imports.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalable&lt;/strong&gt;: As your project grows, your import statements stay clean.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Setting Up Aliases in Angular
&lt;/h3&gt;

&lt;p&gt;Adding aliases is quick and easy.  &lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1: Update &lt;code&gt;tsconfig.json&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;In your &lt;code&gt;tsconfig.json&lt;/code&gt;, go to &lt;code&gt;compilerOptions&lt;/code&gt; and set a &lt;code&gt;baseUrl&lt;/code&gt; to point to your &lt;code&gt;src&lt;/code&gt; directory. Then, add a &lt;code&gt;paths&lt;/code&gt; section to define your aliases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"baseUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"paths"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"@users/*"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"app/users/*"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"@products/*"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"app/products/*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this setup:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@auth/*&lt;/code&gt; maps to &lt;code&gt;src/app/auth/*&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@users/*&lt;/code&gt; maps to &lt;code&gt;src/app/users/*&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@products/*&lt;/code&gt; maps to &lt;code&gt;src/app/products/*&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  Step 2: Update Your Imports
&lt;/h4&gt;

&lt;p&gt;Now, instead of this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AuthService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../../auth/auth.service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AuthService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@services/auth.service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Much cleaner, right?  &lt;/p&gt;




&lt;h4&gt;
  
  
  Step 3: Refactor Existing Imports
&lt;/h4&gt;

&lt;p&gt;I know setting up tsconfig aliases is a big win, but refactoring all those existing imports can feel like a huge chore. That’s exactly why I built &lt;strong&gt;&lt;code&gt;replace-imports-cli&lt;/code&gt;&lt;/strong&gt;! 🚀  &lt;/p&gt;

&lt;h5&gt;
  
  
  Let a Tool Do the Heavy Lifting - &lt;code&gt;replace-imports-cli&lt;/code&gt;
&lt;/h5&gt;

&lt;p&gt;This little tool does the hard work for you. It scans your project, finds all those long relative import paths, and replaces them with the clean aliases you’ve defined in your &lt;code&gt;tsconfig.json&lt;/code&gt;. No more manual fixes. No more guesswork!&lt;/p&gt;

&lt;p&gt;Just run the tool, and it takes care of the rest. In seconds, your imports go from messy to clean and professional.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fupt749o8p27wxrmzd5iy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fupt749o8p27wxrmzd5iy.gif" alt="A GIF showing the tool in action - long relative paths replaced with neat aliases automatically" width="800" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Want to give it a try? Head over to the GitHub repo for all the details:&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://github.com/jzolnowski/replace-imports-cli" rel="noopener noreferrer"&gt;replace-imports-cli on GitHub&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;By combining tsconfig aliases with this CLI tool, you’ll never have to deal with messy relative paths again. Cleaner imports, faster refactoring, and more time to focus on what really matters! 😊&lt;/p&gt;


&lt;h3&gt;
  
  
  Bonus: Cleaner Lazy Loading
&lt;/h3&gt;

&lt;p&gt;You can even use aliases for e.g. lazy loading Angular modules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;  
  &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
    &lt;span class="na"&gt;loadChildren&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@users/user.routes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userRoutes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;  
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes your routes more readable and keeps things consistent.  &lt;/p&gt;




&lt;h3&gt;
  
  
  Why This Matters
&lt;/h3&gt;

&lt;p&gt;Switching to tsconfig aliases isn’t just about making your code look nicer (though that’s a big plus!). It also:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Saves time when refactoring - Moving files doesn’t mean endless fixes to import paths.
&lt;/li&gt;
&lt;li&gt;Makes onboarding new team members easier—they’ll instantly understand where imports are coming from.&lt;/li&gt;
&lt;li&gt;Makes it easier to trace where entities are used, helping you identify and prevent potential circular dependency issues.&lt;/li&gt;
&lt;li&gt;Helps your project scale without creating a tangled web of relative paths.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Works in Any TypeScript Project
&lt;/h3&gt;

&lt;p&gt;Aliases aren’t limited to any framework - they work anywhere you’re using TypeScript. From React, Angular, Vue to Node, NestJS etc., you can enjoy clean, readable imports across all your projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ready to Clean Things Up?
&lt;/h3&gt;

&lt;p&gt;Take a few minutes to set up aliases in your Angular app, and you’ll never want to go back to those long relative paths. Trust me, your future self will thank you. 🙌  &lt;/p&gt;

</description>
      <category>typescript</category>
      <category>webdev</category>
      <category>cleancode</category>
      <category>developertips</category>
    </item>
    <item>
      <title>Level Up Your App's Speed with `NgOptimizedImage`</title>
      <dc:creator>Jarosław Żołnowski</dc:creator>
      <pubDate>Sun, 10 Nov 2024 21:51:09 +0000</pubDate>
      <link>https://dev.to/jzolnowski/supercharge-angular-app-with-ngoptimizedimage-56j4</link>
      <guid>https://dev.to/jzolnowski/supercharge-angular-app-with-ngoptimizedimage-56j4</guid>
      <description>&lt;p&gt;If you've worked on a web app, you know that images can be a big deal for both design and performance. While they make pages look great, they can also slow everything down. That’s where Angular’s &lt;code&gt;NgOptimizedImage&lt;/code&gt; directive comes in. It’s a handy tool for optimizing images, so they load faster without losing quality. Let’s dive into how this directive can make your Angular app snappier and improve the user experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Optimize Images Anyway?
&lt;/h2&gt;

&lt;p&gt;We all want our apps to look good, but images come with a cost—longer load times. Optimizing images can dramatically improve performance metrics, especially the Largest Contentful Paint (LCP), which measures how fast the largest piece of content appears on the screen. This is huge for user experience and SEO, and Angular’s &lt;code&gt;NgOptimizedImage&lt;/code&gt; directive makes it easy to get it right without manual tweaks.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Features of &lt;code&gt;NgOptimizedImage&lt;/code&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Responsive Images with &lt;code&gt;srcSet&lt;/code&gt; and &lt;code&gt;sizes&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;srcSet&lt;/code&gt; and &lt;code&gt;sizes&lt;/code&gt; attributes allow the browser to load the right image size for each device, which is especially helpful for performance. The great thing about Angular’s &lt;code&gt;NgOptimizedImage&lt;/code&gt; directive is that it generates the &lt;code&gt;srcSet&lt;/code&gt; for you, so you don’t need to do it manually.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;ngSrc=&lt;/span&gt;&lt;span class="s"&gt;"angular.jpg"&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;
  &lt;span class="na"&gt;sizes=&lt;/span&gt;&lt;span class="s"&gt;"80vw"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;sizes="80vw"&lt;/code&gt; sets the image to 80% of the viewport width. Angular will handle the rest, creating a &lt;code&gt;srcSet&lt;/code&gt; with various resolutions so that each device gets the best fit. This saves time and ensures a smooth load no matter the screen size.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Customizing Image Breakpoints
&lt;/h3&gt;

&lt;p&gt;If you’re working with specific screen sizes, Angular lets you customize breakpoints by setting an &lt;code&gt;IMAGE_CONFIG&lt;/code&gt; token. This way, you can pick just the breakpoints that match your app’s design.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
  &lt;span class="na"&gt;provide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IMAGE_CONFIG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;useValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;breakpoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;384&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;640&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;750&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now Angular will only generate images for 384px, 640px, and 750px, which keeps your file sizes smaller and your app faster.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Prioritizing Key Images with &lt;code&gt;priority&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Ever noticed how long it can take to load a big image like a banner? The &lt;code&gt;priority&lt;/code&gt; attribute tells Angular which images are critical for loading first. If you set &lt;code&gt;priority&lt;/code&gt;, Angular preloads the image, making sure it appears quickly, improving that all-important LCP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;ngSrc=&lt;/span&gt;&lt;span class="s"&gt;"hero.jpg"&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"1200"&lt;/span&gt;
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"600"&lt;/span&gt;
  &lt;span class="na"&gt;priority&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For server-side rendered apps, Angular even adds a &lt;code&gt;&amp;lt;link rel="preload"&amp;gt;&lt;/code&gt; tag for these images, so they start loading right away. This is perfect for hero images or banners that you want users to see immediately.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Fill Mode for Flexible Layouts
&lt;/h3&gt;

&lt;p&gt;Need an image to fill a container, like a background? &lt;code&gt;fill&lt;/code&gt; mode has you covered. It lets an image scale to fit the container without needing fixed dimensions, which is perfect for layouts with unknown widths or heights.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;ngSrc=&lt;/span&gt;&lt;span class="s"&gt;"background.jpg"&lt;/span&gt; &lt;span class="na"&gt;fill&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just make sure your container has &lt;code&gt;position: relative&lt;/code&gt;, &lt;code&gt;absolute&lt;/code&gt;, or &lt;code&gt;fixed&lt;/code&gt;, so the image fills it properly. This feature is great for responsive layouts where you want images to adapt smoothly.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Lazy Loading for Off-Screen Images
&lt;/h3&gt;

&lt;p&gt;Angular makes lazy loading effortless with &lt;code&gt;loading="lazy"&lt;/code&gt;, which defers loading images until they’re about to be visible. This reduces the initial page load and is awesome for things like image galleries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;ngSrc=&lt;/span&gt;&lt;span class="s"&gt;"thumbnail.jpg"&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;
  &lt;span class="na"&gt;loading=&lt;/span&gt;&lt;span class="s"&gt;"lazy"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just be cautious with images that are crucial to the layout, like a logo. For these, skip lazy loading to ensure they load right away.&lt;/p&gt;




&lt;h3&gt;
  
  
  6. Placeholders for a Better Loading Experience
&lt;/h3&gt;

&lt;p&gt;Nothing kills user experience like a blank loading image. With &lt;code&gt;placeholder&lt;/code&gt;, you can show a temporary low-res version or even a Base64-encoded preview while the main image loads. This provides a smoother experience as users see a preview of the image right away.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;ngSrc=&lt;/span&gt;&lt;span class="s"&gt;"profile.jpg"&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;
  &lt;span class="na"&gt;placeholder&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you use a CDN, you can generate low-res placeholders automatically. Just keep them small (under 4 KB) to avoid slowing down the load. Angular will even throw an error if the placeholder size is too big, which is a good reminder to keep things light.&lt;/p&gt;




&lt;h2&gt;
  
  
  CDN Integration for Faster Image Delivery
&lt;/h2&gt;

&lt;p&gt;By using a Content Delivery Network (CDN) with &lt;code&gt;NgOptimizedImage&lt;/code&gt;, you get faster load times because images are served from servers closer to your users. CDNs cache content across the globe, meaning shorter load times and less data travel, which makes a huge difference, especially for users far from your primary server.&lt;/p&gt;

&lt;p&gt;CDNs also often compress images, ensuring the best quality at the smallest size, which boosts performance even further. When combined with &lt;code&gt;NgOptimizedImage&lt;/code&gt;, CDNs can help you build a fast, responsive app that works well for users everywhere.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Practical Example
&lt;/h2&gt;

&lt;p&gt;Now, let's look at a real-world example to see how the &lt;code&gt;NgOptimizedImage&lt;/code&gt; directive can make a big difference in performance. Imagine we’re building a gaming site that displays game cover images.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkqm51htljzefc1pao0rq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkqm51htljzefc1pao0rq.png" alt="Preview of the Gaming Site" width="800" height="656"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s the initial setup with the standard &lt;code&gt;src&lt;/code&gt; attribute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"1250"&lt;/span&gt;
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"600"&lt;/span&gt;
  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://via.assets.so/game.png?id=12"&lt;/span&gt;
  &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Assassin's Creed Game Cover Art"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display: flex; gap: 25px; margin-top: 25px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
    &lt;span class="na"&gt;*ngFor=&lt;/span&gt;&lt;span class="s"&gt;"let image of list; trackBy: $index"&lt;/span&gt;
    &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://via.assets.so/game.png?id=16"&lt;/span&gt;
    &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"400"&lt;/span&gt;
    &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;
    &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Thumbnails Movie Gallery"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we analyze the page in Lighthouse, the First Contentful Paint (FCP) comes in at 1.4 seconds, while the Largest Contentful Paint (LCP) lags behind at 13.5 seconds—not ideal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmu518fv7ngysn1olp7xj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmu518fv7ngysn1olp7xj.png" alt="Lighthouse Performance Score for Non-Optimized Images" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By making a few tweaks with &lt;code&gt;NgOptimizedImage&lt;/code&gt;, we can get those numbers way down:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"1250"&lt;/span&gt;
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"600"&lt;/span&gt;
  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"game.png?id=12"&lt;/span&gt;
  &lt;span class="na"&gt;ngSrcset=&lt;/span&gt;&lt;span class="s"&gt;"400w, 800w, 1200w"&lt;/span&gt;
  &lt;span class="na"&gt;sizes=&lt;/span&gt;&lt;span class="s"&gt;"(max-width: 600px) 960px, 100vw"&lt;/span&gt;
  &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Witcher II Game Cover Art"&lt;/span&gt;
  &lt;span class="na"&gt;priority&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display: flex; gap: 25px; margin-top: 25px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
    &lt;span class="na"&gt;*ngFor=&lt;/span&gt;&lt;span class="s"&gt;"let image of list; trackBy: $index"&lt;/span&gt;
    &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"400"&lt;/span&gt;
    &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;
    &lt;span class="na"&gt;[ngSrc]=&lt;/span&gt;&lt;span class="s"&gt;"game.png?id=16"&lt;/span&gt;
    &lt;span class="na"&gt;ngSrcset=&lt;/span&gt;&lt;span class="s"&gt;"100w, 200w, 400w"&lt;/span&gt;
    &lt;span class="na"&gt;sizes=&lt;/span&gt;&lt;span class="s"&gt;"(max-width: 600px) 200px, 400px"&lt;/span&gt;
    &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Thumbnails Movie Gallery"&lt;/span&gt;
    &lt;span class="na"&gt;priority&lt;/span&gt;
  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To go the extra mile, we add a &lt;code&gt;preconnect&lt;/code&gt; link for our image server in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"preconnect"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://via.assets.so/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in our app configuration, we set up a custom image loader for our CDN (e.g., &lt;code&gt;Imgix&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;appConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ApplicationConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;provideImgixLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://via.assets.so/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these small adjustments, we see a huge performance boost—FCP drops to just 0.2 seconds, and LCP is down to a quick 0.7 seconds! This is a perfect example of how &lt;code&gt;NgOptimizedImage&lt;/code&gt; can make a real difference in your app’s speed and user experience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F78mbxif4ycd3rw7rwcci.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F78mbxif4ycd3rw7rwcci.png" alt="Lighthouse Performance Score for Optimized Images" width="800" height="464"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Angular’s &lt;code&gt;NgOptimizedImage&lt;/code&gt; is a fantastic tool for improving image handling and app performance. Whether you’re working with responsive images, lazy loading, or CDN integration, this directive makes it easy to get things right. With these optimizations, you’ll have a faster, smoother app that keeps users happy. Give &lt;code&gt;NgOptimizedImage&lt;/code&gt; a try and see the difference in your next project!&lt;/p&gt;

</description>
      <category>performance</category>
      <category>angular</category>
      <category>imageoptimization</category>
      <category>lcp</category>
    </item>
    <item>
      <title>Exploring Angular's Change Detection: In-Depth Analysis</title>
      <dc:creator>Jarosław Żołnowski</dc:creator>
      <pubDate>Sun, 07 Jul 2024 22:18:19 +0000</pubDate>
      <link>https://dev.to/jzolnowski/exploring-angulars-change-detection-in-depth-analysis-h3j</link>
      <guid>https://dev.to/jzolnowski/exploring-angulars-change-detection-in-depth-analysis-h3j</guid>
      <description>&lt;h2&gt;
  
  
  Understanding Change Detection
&lt;/h2&gt;

&lt;p&gt;Change detection in Angular is a key process that keeps the app's state and user interface in sync. It's how Angular makes sure our UI updates when the underlying data changes. Without it, any changes in your app wouldn't show up in the UI automatically, making the app inconsistent and unreliable. Change detection is important because it keeps the UI accurate, ensuring every user action, data fetch, or event is shown correctly, making the app responsive and user-friendly.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Change Detection Works in Angular
&lt;/h2&gt;

&lt;p&gt;The change detection process in Angular involves two main stages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Marking the Component as Dirty:&lt;/strong&gt; This initial stage occurs when an event that can alter the state of a component happens. For instance, a user clicks a button, which triggers Angular to mark the affected component as &lt;code&gt;dirty&lt;/code&gt;. This marking indicates that the component requires a check-up for potential changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Refreshing the View:&lt;/strong&gt; This is where &lt;code&gt;zone.js&lt;/code&gt; comes into play. zone.js is a library that helps Angular track asynchronous operations like XHR requests, DOM events, and timers (e.g., &lt;code&gt;setInterval&lt;/code&gt;, &lt;code&gt;setTimeout&lt;/code&gt;). When an asynchronous event occurs, Angular captures it through the &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/change_detection/scheduling/ng_zone_scheduling.ts#L47-L60" rel="noopener noreferrer"&gt;onMicrotaskEmpty&lt;/a&gt; Observable:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_onMicrotaskEmptySubscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;zone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onMicrotaskEmpty&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;changeDetectionScheduler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runningTick&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;zone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;applicationRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tick&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/application/application_ref.ts#L585C9-L592C10" rel="noopener noreferrer"&gt;traverse the view tree&lt;/a&gt; to detect and propagate any changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;_lView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;notifyErrorHandler&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_views&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;detectChangesInViewIfRequired&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;_lView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;notifyErrorHandler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;isFirstPass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;zonelessEnabled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Angular, a &lt;code&gt;view&lt;/code&gt; refers to an instance of &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/render3/view_ref.ts#L45" rel="noopener noreferrer"&gt;ViewRef&lt;/a&gt;. Think of &lt;code&gt;ViewRef&lt;/code&gt; as a box that contains a bunch of important information about the component, such as the current state of inputs, the template, directives being used, and binding statuses. Each component has its own &lt;code&gt;ViewRef&lt;/code&gt; box, making it easier for Angular to manage and update components during change detection.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;detectChangesInViewIfRequired&lt;/code&gt; method triggers the &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/render3/instructions/change_detection.ts#L458" rel="noopener noreferrer"&gt;detectChangesInView&lt;/a&gt;, which defines the criteria for checking components, inspecting various flags associated with the view and its mode, to determine if any updates are necessary.&lt;/p&gt;

&lt;p&gt;If the view needs refreshing, the &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/render3/instructions/change_detection.ts#L497" rel="noopener noreferrer"&gt;refreshView&lt;/a&gt; method is called. This method executes the &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/render3/instructions/shared.ts#L445" rel="noopener noreferrer"&gt;template function&lt;/a&gt; (which is a component template compiled into a regular JavaScript function) with the render flags and context to generate the component view and starts a chain reaction by triggering event detection for the view's child components through the &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/render3/instructions/change_detection.ts#L305" rel="noopener noreferrer"&gt;detectChangesInChildComponents&lt;/a&gt; method.&lt;/p&gt;

&lt;p&gt;So to perform change detection, Angular traverses the views' tree and executes template functions on each component.&lt;/p&gt;




&lt;h2&gt;
  
  
  Default Change Detection
&lt;/h2&gt;

&lt;p&gt;In the beginning, most of us used Default change detection - it's like being in the middle of a bustling city – there's noise everywhere, distractions pulling your attention in every direction. This is how it was with Angular's default change detection. It keeps an eye on everything, even when nothing's happening. And sure, it works, but it's a bit overkill, causing performance hiccups, especially as your app grows.&lt;/p&gt;

&lt;p&gt;This strategy is the default change detection mechanism, and it’s applied automatically unless we explicitly override it with an OnPush strategy. It relies on the &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/render3/instructions/change_detection.ts#L464-L467" rel="noopener noreferrer"&gt;CheckAlways&lt;/a&gt; flag which means that Angular will run change detection for all components whenever any event occurs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;shouldRefreshView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;ChangeDetectionMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Global&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;LViewFlags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CheckAlways&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So if this flag is set, then it calls the mentioned &lt;code&gt;refreshView&lt;/code&gt; method (&lt;code&gt;shouldRefreshView&lt;/code&gt; flag is set to &lt;code&gt;true&lt;/code&gt;),&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shouldRefreshView&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;refreshView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lView&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;CONTEXT&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which refreshes not just the current view but also all its child views, if there are any. This ensures everything stays consistent, but it can be inefficient for larger apps because it might do more checks than needed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F68fmdqi4mfyfs8t204ul.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F68fmdqi4mfyfs8t204ul.gif" alt="Click on Component D, which triggers an animation throughout the entire DOM tree from top bo the bottom" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, it's kind of like a domino effect, making sure the entire component tree gets updated, whatever happens.&lt;/p&gt;

&lt;p&gt;We have the ability to control this one way or another. We can explicitly detach and reattach the view from the change detection tree using &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/render3/view_ref.ts#L220-L222" rel="noopener noreferrer"&gt;detach()&lt;/a&gt; and &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/render3/view_ref.ts#L280-L283" rel="noopener noreferrer"&gt;reattach()&lt;/a&gt; methods respectively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
 &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;detached&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Detached Component`&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DetachedComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;cdr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ChangeDetectorRef&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;cdr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;detach&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we detach the view from the change detection, Angular will skip it, regardles of any changes chappend.&lt;/p&gt;




&lt;h2&gt;
  
  
  OnPush Change Detection Strategy
&lt;/h2&gt;

&lt;p&gt;For better performance, Angular offers the &lt;code&gt;OnPush&lt;/code&gt; change detection strategy. This strategy tells Angular to skip change detection for the component unless one of its inputs changes, we mark component to check using &lt;code&gt;markForCheck&lt;/code&gt; method or an event occurs, for example a XHR request handled by an &lt;code&gt;async&lt;/code&gt; pipe.&lt;/p&gt;

&lt;p&gt;By focusing on what's changed, rather than checking everything all the time, &lt;code&gt;OnPush&lt;/code&gt; makes apps faster and more efficient, reduces unnecessary updates, improves performance, and prevents potential disasters.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;OnPush&lt;/code&gt; helps optimize performance by reducing the number of times change detection runs, especially in large and complex applications.&lt;/p&gt;

&lt;p&gt;So, how does it work? I mentioned that &lt;code&gt;OnPush&lt;/code&gt; change detection gets triggered when we do things like setting a new Input value in a child component.&lt;/p&gt;

&lt;p&gt;Now, let's get back to the Angular source code, and verify the part that runs when we &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/render3/component_ref.ts#L442-L469" rel="noopener noreferrer"&gt;set a new Input value&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, when the &lt;code&gt;setInput&lt;/code&gt; method is called, it confirms that the Input value actually has been changed,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;previousInputValues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
  &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;previousInputValues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;marking the component view as &lt;code&gt;Dirty&lt;/code&gt; in the &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/render3/component_ref.ts#L460" rel="noopener noreferrer"&gt;markViewDirty&lt;/a&gt;  method, which basically tells Angular, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Hey, this child component's view needs updating, so take a look next time you check for changes."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The same idea applies when, for example, we are using an &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/common/src/pipes/async_pipe.ts#L102" rel="noopener noreferrer"&gt;Async pipe&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It subscribes to observables, which updates the latest value by &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/common/src/pipes/async_pipe.ts#L194" rel="noopener noreferrer"&gt;calling the markForCheck function&lt;/a&gt;,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;_updateLatestValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_latestValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;markForCheckOnValueUpdate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_ref&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;markForCheck&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which, in turn, triggers the &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/render3/view_ref.ts#L164" rel="noopener noreferrer"&gt;markViewDirty&lt;/a&gt; method.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;markForCheck&lt;/code&gt; is also used in a few other scenarios. For example if we want to initiate the change detection manually, we handle the DOM event, or attaching, detaching a view. And in all these scenarios at some point we call the &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/render3/instructions/mark_view_dirty.ts#L41-L50" rel="noopener noreferrer"&gt;markViewDirty&lt;/a&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lView&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;lView&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;FLAGS&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;|=&lt;/span&gt; &lt;span class="nx"&gt;dirtyBitsToUse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getLViewParent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lView&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isRootView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lView&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;lView&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;lView&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method is like a domino effect –  it starts with the specified view and moves up the family tree, by &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/render3/instructions/mark_view_dirty.ts#L45" rel="noopener noreferrer"&gt;checking if there’s a parent&lt;/a&gt;,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isRootView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lView&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;marking each view along the path as &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/render3/instructions/mark_view_dirty.ts#L42" rel="noopener noreferrer"&gt;Dirty&lt;/a&gt;, meaning they all need checking.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dirtyBitsToUse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;isRefreshingViews&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;LViewFlags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Dirty&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;LViewFlags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RefreshView&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;LViewFlags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Dirty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lView&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nx"&gt;lView&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;FLAGS&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;|=&lt;/span&gt; &lt;span class="nx"&gt;dirtyBitsToUse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="err"&gt;…&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And when it's time to do the actual checking, Angular &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/render3/instructions/change_detection.ts#L475-L479" rel="noopener noreferrer"&gt;looks at those views marked as dirty&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;shouldRefreshView&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;LViewFlags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Dirty&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
  &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;ChangeDetectionMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Global&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
  &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isInCheckNoChangesPass&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a component's view is marked as &lt;code&gt;Dirty&lt;/code&gt;, it means something in that component has changed, and it needs to be re-rendered. And we do that by calling the &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/render3/instructions/change_detection.ts#L497" rel="noopener noreferrer"&gt;refreshView&lt;/a&gt; method.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzh36pb3hlvr8hobv25pq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzh36pb3hlvr8hobv25pq.gif" alt="Click on Component D triggers an animation on the clicked element and all its ancestors, starting from the root component" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we click on the component, it triggers a change detection in the component itself and all its parent components, which is exactly what we should expect, because we marked all its ancestors as &lt;code&gt;Dirty&lt;/code&gt; in the &lt;code&gt;markViewDirty&lt;/code&gt; method.&lt;/p&gt;




&lt;h2&gt;
  
  
  Signals Era
&lt;/h2&gt;

&lt;p&gt;Since version 16, Angular has been introducing Signals - a wrapper around a value that can notify interested consumers when that value changes. It can contain any value, from simple primitives to complex data structures, and we can read the value through a getter function, which allows Angular to track where the signal is used.&lt;/p&gt;

&lt;p&gt;Now, the cool part is, Angular allows us to utilize this Signal power and combine it with the &lt;code&gt;OnPush&lt;/code&gt; strategy to mark certain components for updates.&lt;/p&gt;

&lt;p&gt;This little trick eliminates the need for unnecessary checks on components, whether they're parent or child elements.&lt;/p&gt;

&lt;p&gt;Let's see what makes the signals work the way they do. Whenever we tweak a signal within a component's template, using methods like &lt;code&gt;set()&lt;/code&gt; or &lt;code&gt;update()&lt;/code&gt;, it's like setting off a little chain reaction. &lt;/p&gt;

&lt;p&gt;First, Angular calls &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/primitives/signals/src/signal.ts#L71" rel="noopener noreferrer"&gt;signalSetFn&lt;/a&gt;, which will &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/primitives/signals/src/signal.ts#L108" rel="noopener noreferrer"&gt;send out a notification&lt;/a&gt; to the live consumer waiting in the view,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;signalValueChanged&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SignalNode&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;…&lt;/span&gt;
  &lt;span class="nf"&gt;producerNotifyConsumers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="err"&gt;…&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;making it go, &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/primitives/signals/src/graph.ts#L304C9-L304C26" rel="noopener noreferrer"&gt;"Hey, I'm dirty!"&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;consumer&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;liveConsumerNode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dirty&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;consumerMarkDirty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, it &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/render3/util/view_utils.ts#L262" rel="noopener noreferrer"&gt;marks all its ancestors, right up to the root, with a flag called HasChildViewsToRefresh&lt;/a&gt;, indicating &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Hey, I've got some child views here that need to be refreshed."&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;FLAGS&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;LViewFlags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HasChildViewsToRefresh&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;FLAGS&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;|=&lt;/span&gt; &lt;span class="nx"&gt;LViewFlags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HasChildViewsToRefresh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;viewAttachedToChangeDetector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getLViewParent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we take a look closer, we'll see that this method is pretty similar to the &lt;code&gt;markViewDirty&lt;/code&gt; method. The difference is, instead of marking all parent views with the &lt;code&gt;Dirty&lt;/code&gt; flag, we mark them with the &lt;code&gt;HasChildViewToRefresh&lt;/code&gt; flag.&lt;/p&gt;

&lt;p&gt;Now, as you already know, the change detection mechanism consists of two parts and the subsequent part traverses the tree of views. So let's back into our &lt;code&gt;detectChangesInView&lt;/code&gt; method that evaluates whether a view requires updating.&lt;/p&gt;

&lt;p&gt;Now, here's the clever part - when a view is &lt;a href="https://github.com/angular/angular/blob/18.1.0/packages/core/src/render3/instructions/change_detection.ts#L498-L504" rel="noopener noreferrer"&gt;marked with this HasChildViewsToRefresh flag&lt;/a&gt;, there's no need to re-render it. Angular skips right ahead to checking out the child component view if there's any.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;LViewFlags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HasChildViewsToRefresh&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;detectChangesInEmbeddedViews&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ChangeDetectionMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Targeted&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;components&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;components&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;detectChangesInChildComponents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ChangeDetectionMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Targeted&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This smart shortcut helps Angular avoid wasting time on unnecessary stuff, ensuring smooth and efficient operation!&lt;/p&gt;

&lt;p&gt;When we use e.g. the &lt;code&gt;setInterval&lt;/code&gt; function to update the signal value in &lt;code&gt;Component D&lt;/code&gt;, only the components directly touched by the signal change actually get refreshed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawent00qlx3wc54z0vpn.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawent00qlx3wc54z0vpn.gif" alt="Click on Component D, which triggers an animation only on itself" width="1402" height="656"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;OnPush&lt;/code&gt; within Signals is like a sniper shot for detecting changes. It allows us to specify which components should be re-rendered when certain signals change. This means that instead of refreshing the entire component tree or a single branch when using &lt;code&gt;OnPush&lt;/code&gt;, we only re-render the components directly affected by the signal change.&lt;/p&gt;




&lt;h2&gt;
  
  
  Wrap up
&lt;/h2&gt;

&lt;p&gt;Default change detection relies on the &lt;code&gt;CheckAlways&lt;/code&gt; flag, triggering updates for the entire view tree, whatever happens. This keeps everything consistent but can be overkill, causing unnecessary performance hits as the app grows.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;OnPush&lt;/code&gt; change detection is a powerful optimization technique in Angular. It ensures that components are only re-rendered when their inputs change, when events occur within the component or when we manually trigger change detection using the &lt;code&gt;markForCheck&lt;/code&gt; method. It's important to note that when we use &lt;code&gt;OnPush&lt;/code&gt;, the change detection refreshes not only the component itself but also all its parent components in the component tree.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;OnPush&lt;/code&gt; within Signals is a more targeted approach to change detection. It allows us to specify which components should be re-rendered when certain signals change. This means that instead of refreshing the entire component tree or a single branch when using &lt;code&gt;OnPush&lt;/code&gt;, we only re-render the components directly affected by the signal change.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>signals</category>
      <category>changedetection</category>
      <category>indepth</category>
    </item>
  </channel>
</rss>
