Logo

dev-resources.site

for different kinds of informations.

Deferred loading with @defer: Optimize Your App's Performance

Published at
1/15/2025
Categories
angular
webdev
frontend
tutorial
Author
hassantayyab
Categories
4 categories in total
angular
open
webdev
open
frontend
open
tutorial
open
Author
12 person written this
hassantayyab
open
Deferred loading with @defer: Optimize Your App's Performance

Angular continues to innovate with each release, and the introduction of @defer blocks in Angular v19 is a game-changer for optimizing web application performance. This blog post explores Angular's @defer feature, explaining its functionalities, use cases, and practical code examples to help you leverage it effectively.


What are defer Blocks?

Deferrable views, also known as @defer blocks, enable lazy loading for sections of your Angular templates. They reduce the initial bundle size by deferring the loading of code that is not essential for the initial rendering of a page. This improves initial load times and Core Web Vitals (CWV) such as Largest Contentful Paint (LCP) and Time to First Byte (TTFB).

You can declaratively wrap a section of your template in a @defer block to defer its loading:

@defer {
  <large-component />
}
Enter fullscreen mode Exit fullscreen mode

This loads the dependencies of large-component only when required, improving performance.


Key Features of defer Blocks

1. Placeholders for Better User Experience

The @placeholder block lets you show content while the deferred section is being loaded.

@defer {
  <large-component />
} @placeholder {
  <p>Loading...</p>
}
Enter fullscreen mode Exit fullscreen mode

Use Case: Use placeholders to provide immediate feedback to users while content loads.


2. Loading Indicators

The @loading block is shown after the placeholder and during the loading process. It replaces the placeholder content.

@defer {
  <large-component />
} @loading {
  <img alt="Loading..." src="loading.gif" />
} @placeholder {
  <p>Loading...</p>
}
Enter fullscreen mode Exit fullscreen mode

Parameters:

  • minimum: Minimum time to show the loading block.
  • after: Time after loading starts to display the loading block.

Example:

@defer {
  <large-component />
} @loading (minimum 1s; after 100ms) {
  <img alt="Loading..." src="loading.gif" />
}
Enter fullscreen mode Exit fullscreen mode

3. Error Handling

The @error block displays content when deferred loading fails.

@defer {
  <large-component />
} @error {
  <p>Failed to load content. Please try again.</p>
}
Enter fullscreen mode Exit fullscreen mode

Triggers for Controlling Deferred Content

1. Idle Trigger

Defers loading until the browser is idle:

@defer (on idle) {
  <large-component />
} @placeholder {
  <p>Loading...</p>
}
Enter fullscreen mode Exit fullscreen mode

2. Viewport Trigger

Loads content when it enters the viewport:

@defer (on viewport) {
  <large-component />
} @placeholder {
  <p>Scroll down to load...</p>
}
Enter fullscreen mode Exit fullscreen mode

3. Interaction Trigger

Loads content upon user interaction, such as clicks:

@defer (on interaction) {
  <large-component />
} @placeholder {
  <button>Click to load</button>
}
Enter fullscreen mode Exit fullscreen mode

4. Hover Trigger

Loads content when the mouse hovers over a specified area:

@defer (on hover) {
  <large-component />
} @placeholder {
  <p>Hover to load content...</p>
}
Enter fullscreen mode Exit fullscreen mode

5. Timer Trigger

Loads content after a set duration:

@defer (on timer(2s)) {
  <large-component />
} @placeholder {
  <p>Loading in 2 seconds...</p>
}
Enter fullscreen mode Exit fullscreen mode

6. Custom Conditional Trigger

Loads content based on a custom condition:

@defer (when isReady) {
  <large-component />
} @placeholder {
  <p>Waiting for readiness...</p>
}
Enter fullscreen mode Exit fullscreen mode

Combining Prefetching and Deferred Loading

You can specify a prefetch trigger to preload dependencies before they are needed:

@defer (on interaction; prefetch on idle) {
  <large-component />
} @placeholder {
  <button>Click to load</button>
}
Enter fullscreen mode Exit fullscreen mode

This starts prefetching when the browser is idle but only renders the content when the user interacts.


Testing defer Blocks

Angular provides APIs to test @defer blocks using TestBed. You can control and verify different states manually:

it('should test defer block states', async () => {
  TestBed.configureTestingModule({ deferBlockBehavior: DeferBlockBehavior.Manual });

  @Component({
    template: `
      @defer {
        <large-component />
      } @placeholder {
        Placeholder
      } @loading {
        Loading...
      }
    `
  })
  class TestComponent {}

  const fixture = TestBed.createComponent(TestComponent);
  const deferBlock = (await fixture.getDeferBlocks())[0];

  expect(fixture.nativeElement.innerHTML).toContain('Placeholder');
  await deferBlock.render(DeferBlockState.Loading);
  expect(fixture.nativeElement.innerHTML).toContain('Loading...');
  await deferBlock.render(DeferBlockState.Complete);
  expect(fixture.nativeElement.innerHTML).toContain('large-component works!');
});
Enter fullscreen mode Exit fullscreen mode

Best Practices for Using defer Blocks

  1. Avoid Nested Defers: Use distinct triggers for nested @defer blocks to prevent cascading loads.
  2. Prevent Layout Shifts: Avoid deferring components visible during initial load to minimize cumulative layout shift (CLS).

Cheat Sheet for Angular Blocks

  • Basic usage: @defer { <component /> } - Defers the content inside the block.
  • Placeholder: @defer { <cmp /> } @placeholder { <p>Loading...</p> } - Placeholder shown before loading.
  • Loading: @defer { <cmp /> } @loading { <p>Loading...</p> } - Shown during loading process.
  • Error Handling: @defer { <cmp /> } @error { <p>Error...</p> } - Handles loading failures.
  • Triggers: @defer (on idle) - Controls when loading starts.
  • Prefetch: @defer (on interaction; prefetch on idle) - Preloads dependencies early.

Additional Resources

Start exploring Angular's @defer feature today and transform the performance of your Angular applications!

tutorial Article's
30 articles in total
Tutorials offer step-by-step instructions to help learners grasp concepts and complete tasks in various domains.
Favicon
Creating a live HTML, CSS and JS displayer
Favicon
Build Your First AI Application Using LlamaIndex!
Favicon
Creating Arrays with Reference Variables
Favicon
How To Build Beautiful Terminal UIs (TUIs) in JavaScript 2: forms!
Favicon
Chronicles of Supermarket website
Favicon
Easy development environments with Nix and Nix flakes!
Favicon
ruby -run
Favicon
Основы изучения Python: Руководство для начинающих
Favicon
How to Use JavaScript to Reduce HTML Code: A Simple Example
Favicon
SQL Performance Tuning: Best Practices for Faster Queries
Favicon
Php Base64 encode/decode – best practices and use cases
Favicon
10 Must-Bookmark Open Source Projects for Developers
Favicon
Easy 301 Redirects For SEO
Favicon
ruby -run, again
Favicon
🚀 New Book Release: "Navigate the Automation Seas" – A Practical Guide to Building Automation Frameworks
Favicon
Top Kubernetes CI/CD Tools in 2025
Favicon
340+ Websites every developer should know
Favicon
Survival Manual: How to Create and Manage a Project in Git
Favicon
Strong Female Role Models in the Sector: Oya Narin
Favicon
Test Scenarios vs. Test Cases: Understanding the Differences
Favicon
Angular validation common functions
Favicon
KDE vs GNOME vs Others: Choosing the Best Linux Desktop Environment in 2025
Favicon
NXP i.MX8MP Platform Porting Driver Tutorial
Favicon
Response Handling Best Practices
Favicon
Why AWS Matters: A Beginner's View
Favicon
How the Internet Works: OSI Model, DNS, TCP vs. UDP, and Essential Concepts for Beginners
Favicon
Resolving Auto-Scroll issues for overflow container in a Nuxt app
Favicon
#131 — Use Association Table to Handle Interval Association
Favicon
Deferred loading with @defer: Optimize Your App's Performance
Favicon
Psychotherapy Technology Advancements

Featured ones: