🚀 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
/adminpage. The key is that the Admin module's assembly (AdminModule.dll) will only be downloaded by the browser when the user navigates to the/adminroute.
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:5001or similar). - Open your browser's Developer Tools (F12) and go to the **Network** tab.
- Initially, visit the Home page (
/). You will notice thatAdminModule.dllis **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 seeAdminModule.dllappear 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.
Comments
Post a Comment