🚀 Hands-On Guide: Assembly Lazy Loading in Blazor WebAssembly

🚀 Hands-On Guide: Assembly Lazy Loading in Blazor WebAssembly

🚀 Hands-On Guide: Assembly Lazy Loading in Blazor WebAssembly

By: Raushan Ranjan
Level: Beginner–Intermediate Blazor Developer
Goal: Speed up your Blazor WebAssembly app by loading heavy features only when the user needs them.

📌 What You’ll Learn

  • What Assembly Lazy Loading is and why it matters.
  • How to split your app into modules that load on demand.
  • Step-by-step demo project with working code.
  • How to test and verify the lazy loading in action.

1️⃣ Understanding Assembly Lazy Loading in Blazor

When you build a Blazor WebAssembly app, all your .dll assemblies (which contain your compiled C# code and Razor components) are downloaded to the user's browser before the first page even loads.

If your application is large or includes many features, this "all-at-once" download can significantly increase the initial loading time, leading to a slower user experience, especially on slower networks.

The solution to this challenge is **Assembly Lazy Loading** — a powerful feature that allows you to load specific assemblies (and the pages/components they contain) only when they are actually required by the user.

Example: An Admin Dashboard page that only managers use should not slow down the initial application load for every other user. With lazy loading, the Admin module's assemblies will only be downloaded when a manager navigates to that specific page.

2️⃣ The Demo We’ll Build

We’ll create a simple Blazor WebAssembly application with two main parts:

  • Main App: This will be your primary Blazor WebAssembly project, loading instantly with a basic Home page.
  • Admin Module (Razor Class Library - RCL): This will be a separate project containing the /admin page. The key is that the Admin module's assembly (AdminModule.dll) will only be downloaded by the browser when the user navigates to the /admin route.

Here's a preview of the project structure:


LazyLoadingDemo/
    Client (Main Blazor WebAssembly App)
    AdminModule (Razor Class Library with Admin page)
        

3️⃣ Step-by-Step Implementation

Step 1 — Create the Projects

Open your terminal or Visual Studio and create the two necessary projects:


dotnet new blazorwasm -n LazyLoadingDemo
dotnet new razorclasslib -n AdminModule
        

Step 2 — Configure the Admin Module for Lazy Loading

Edit the AdminModule/AdminModule.csproj file. Inside the <Project> tags, add an <ItemGroup> that marks this library for lazy loading. This tells the Blazor build process to treat this DLL specially.


<Project Sdk="Microsoft.NET.Sdk.Razor">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <!-- Mark this library for lazy loading -->
    <BlazorWebAssemblyLazyLoad Include="$(MSBuildProjectName).dll" />
  </ItemGroup>

</Project>
        

Step 3 — Add the Admin Page

Create a new folder named Pages inside your AdminModule project, and then create a new Razor component file named Admin.razor within that folder. This will be the page that gets lazy-loaded.


<!-- AdminModule/Pages/Admin.razor -->
@page "/admin"

<h3>Admin Dashboard</h3>
<p>This page is coming from a lazy-loaded assembly 🚀</p>
        

Step 4 — Reference the Module in Main App

In your main Blazor WebAssembly project (LazyLoadingDemo), you need to add a project reference to the AdminModule. Edit the LazyLoadingDemo/LazyLoadingDemo.csproj file and add the following:


<ItemGroup>
  <ProjectReference Include="..\AdminModule\AdminModule.csproj" />
</ItemGroup>
        

Step 5 — Setup Lazy Loading in App.razor

The core logic for lazy loading resides in your main application's App.razor file. This is where you'll intercept navigation and dynamically load the required assemblies.


<!-- LazyLoadingDemo/App.razor -->
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@inject LazyAssemblyLoader AssemblyLoader <!-- Inject the service -->

<Router AppAssembly="@typeof(Program).Assembly"
        OnNavigateAsync="OnNavigateAsync"> <!-- Hook into navigation -->
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <LayoutView Layout="@typeof(MainLayout)">
            <p>Sorry, page not found.</p>
        </LayoutView>
    </NotFound>
</Router>

@if (isLoading)
{
    <div class="loading">Loading admin module...</div> <!-- Simple loading indicator -->
}

@code {
    bool isLoading = false;
    bool adminLoaded = false; <!-- Flag to prevent re-loading -->

    private async Task OnNavigateAsync(NavigationContext args)
    {
        // Check if the navigation is to an admin path AND the admin module hasn't been loaded yet
        if (args.Path.StartsWith("admin", StringComparison.OrdinalIgnoreCase) && !adminLoaded)
        {
            isLoading = true;
            StateHasChanged(); // Update UI to show loading indicator

            try
            {
                // Load the AdminModule.dll assembly
                await AssemblyLoader.LoadAssembliesAsync(new[] { "AdminModule.dll" });
                adminLoaded = true; // Mark as loaded
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine($"Error loading AdminModule: {ex.Message}");
                // Handle error, e.g., show an error message to the user
            }
            finally
            {
                isLoading = false;
                StateHasChanged(); // Hide loading indicator
            }
        }
    }
}
        

Step 6 — Add Navigation Links

Finally, add navigation links to your Shared/NavMenu.razor component so users can actually access the lazy-loaded Admin page.


<!-- Shared/NavMenu.razor -->
<div class="nav-item px-3">
    <NavLink class="nav-link" href="">
        <span class="oi oi-home"></span> Home
    </NavLink>
</div>
<div class="nav-item px-3">
    <NavLink class="nav-link" href="admin">
        <span class="oi oi-lock-locked"></span> Admin
    </NavLink>
</div>
        

Step 7 — Run & Test

Now, run your Blazor WebAssembly application and observe the lazy loading in action:


dotnet run --project LazyLoadingDemo
        
  • Open your browser and navigate to the application (usually https://localhost:5001 or similar).
  • Open your browser's Developer Tools (F12) and go to the **Network** tab.
  • Initially, visit the Home page (/). You will notice that AdminModule.dll is **not** loaded.
  • Now, click the "Admin" link in the navigation menu. Watch the Network tab closely — you will see AdminModule.dll (and any other dependencies it has) download at that moment.

4️⃣ How to Verify Lazy Loading

  • In your browser's **Network Tab**, filter by .dll. You’ll clearly see AdminModule.dll appear in the network requests only when you click the "Admin" link, not on the initial page load.
  • The **first load payload** of your application will be smaller, leading to a faster initial render and a better perceived performance for users who don't need the Admin features immediately.
  • The Admin page will load slightly slower on its first access (due to the extra network call for the DLL), but subsequent visits to the Admin page within the same session will be fast as the DLL will be cached by the browser.

5️⃣ Real-World Use Cases

Assembly lazy loading is incredibly beneficial for optimizing large Blazor WebAssembly applications. Consider using it for:

  • Admin dashboards: Features only accessible to a subset of users.
  • Reporting modules: Complex reports that are not part of the core user flow.
  • Feature-flagged experimental features: New functionalities being tested with a limited audience.
  • Large UI libraries: If you use comprehensive UI component libraries (like Syncfusion, Telerik, Radzen) but only a small portion of their components are used on specific, non-core pages, lazy loading those library assemblies can drastically reduce initial load times.
  • Infrequently accessed pages: Any section of your application that the majority of users don't need on their first visit.

By strategically implementing assembly lazy loading, you can significantly improve the initial startup performance of your Blazor WebAssembly applications, leading to a much better user experience.

Raushan Ranjan

Microsoft Certified Trainer

.NET | Azure | Power Platform | WPF | Qt/QML Developer

Power BI Developer | Data Analyst

📞 +91 82858 62455
🌐 raushanranjan.azurewebsites.net
🔗 linkedin.com/in/raushanranjan

Comments

Popular posts from this blog

Blazor WebAssembly Hosted App Tutorial: Envelope Tracker System

Authentication and Authorization in Blazor

Securing MVC-based Applications Using Blazor