{"id":1743,"date":"2023-11-09T05:00:00","date_gmt":"2023-11-09T13:00:00","guid":{"rendered":"https:\/\/www.angulartraining.com\/daily-newsletter\/?p=1743"},"modified":"2026-03-12T01:48:00","modified_gmt":"2026-03-12T08:48:00","slug":"angular-17-lazy-loading-with-defer","status":"publish","type":"post","link":"https:\/\/www.angulartraining.com\/daily-newsletter\/angular-17-lazy-loading-with-defer\/","title":{"rendered":"Lazy-loading with @defer"},"content":{"rendered":"\n<p>Today, let&#8217;s cover how to fully customize lazy-loading with Angular using <a href=\"https:\/\/angular.dev\/guide\/defer#defer\" target=\"_blank\" rel=\"noopener\" title=\"\">@defer<\/a>.<\/p>\n\n\n\n<p>What&#8217;s great about @defer is that it no longer relies on the Angular router. You can lazy-load any standalone component anywhere, anytime, and on your terms, as you can decide the <a href=\"https:\/\/angular.dev\/guide\/defer#triggers\" target=\"_blank\" rel=\"noopener\" title=\"\">trigger<\/a> to load that component.<\/p>\n\n\n\n<p>Let&#8217;s start with a basic example:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"389\" height=\"124\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2023\/11\/image-11.png\" alt=\"\" class=\"wp-image-1745\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2023\/11\/image-11.png 389w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2023\/11\/image-11-300x96.png 300w\" sizes=\"auto, (max-width: 389px) 100vw, 389px\" \/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>The above code will load the <code>HelloComponent<\/code> as soon as the browser is idle, which means it&#8217;s done loading everything else. While that is happening, we can decide to display a placeholder, and in my case, I decided that such a placeholder would be displayed for a minimum of 2 seconds no matter what. You can use seconds (s) or milliseconds (ms) as a time unit:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"424\" height=\"185\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2023\/11\/image-12.png\" alt=\"\" class=\"wp-image-1746\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2023\/11\/image-12.png 424w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2023\/11\/image-12-300x131.png 300w\" sizes=\"auto, (max-width: 424px) 100vw, 424px\" \/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>You can see the <a href=\"https:\/\/stackblitz.com\/edit\/at-defer?file=src%2Fmain.ts\" target=\"_blank\" rel=\"noopener\" title=\"\">above code in action here on Stackblitz<\/a>. Note that the Angular Language service was updated accordingly, so VS Code (Stackblitz is a web-based VS code), Webstorm, and other IDEs already know about the new <code>@defer<\/code> syntax and do proper highlighting of it!<\/p>\n\n\n\n<p>We can also specify a <a href=\"https:\/\/angular.dev\/guide\/defer#loading\" target=\"_blank\" rel=\"noopener\" title=\"\">loading<\/a> template and an <a href=\"https:\/\/angular.dev\/guide\/defer#error\" target=\"_blank\" rel=\"noopener\" title=\"\">error template<\/a>, all customizable with a minimum amount of time during which we would display those templates (<a href=\"https:\/\/stackblitz.com\/edit\/at-defer-loading?file=src%2Fmain.ts\" target=\"_blank\" rel=\"noopener\" title=\"\">example on Stackblitz here<\/a>):<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"426\" height=\"362\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2023\/11\/image-13.png\" alt=\"\" class=\"wp-image-1747\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2023\/11\/image-13.png 426w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2023\/11\/image-13-300x255.png 300w\" sizes=\"auto, (max-width: 426px) 100vw, 426px\" \/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>I used &#8220;big&#8221; numbers to see the different states in my examples. Note that <code>@loading<\/code> supports an &#8220;after &#8221; option only to show the loading template if loading takes more than a certain amount of time, so you don&#8217;t have to display anything if the component loads quickly. Both parameters are optional:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"428\" height=\"96\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2023\/11\/image-14.png\" alt=\"\" class=\"wp-image-1749\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2023\/11\/image-14.png 428w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2023\/11\/image-14-300x67.png 300w\" sizes=\"auto, (max-width: 428px) 100vw, 428px\" \/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>These are the different new blocks available with <code>@defer<\/code>. <\/p>\n\n\n\n<p>Next, you can look at the <a href=\"https:\/\/www.angulartraining.com\/daily-newsletter\/angular-17-trigger-options-for-defer\/\" target=\"_blank\" rel=\"noopener\" title=\"\">different trigger options<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today, let&#8217;s cover how to fully customize lazy-loading with Angular using @defer. What&#8217;s great about @defer is that it no longer relies on the Angular router. You can lazy-load any standalone component anywhere, anytime, and on your terms, as you can decide the trigger to load that component. Let&#8217;s start with a basic example: The [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,20,7],"tags":[],"class_list":["post-1743","post","type-post","status-publish","format-standard","hentry","category-angular","category-performance","category-template-syntax"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/posts\/1743","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/comments?post=1743"}],"version-history":[{"count":5,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/posts\/1743\/revisions"}],"predecessor-version":[{"id":2391,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/posts\/1743\/revisions\/2391"}],"wp:attachment":[{"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/media?parent=1743"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/categories?post=1743"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/tags?post=1743"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}