Lazy load assemblies in ASP.NET Core Blazor WebAssembly
Blazor WebAssembly app startup performance can be improved by waiting to load app assemblies until the assemblies are required, which is called lazy loading.
This article's initial sections cover the app configuration. For a working demonstration, see the Complete example section at the end of this article.
This article only applies to Blazor WebAssembly apps. Assembly lazy loading doesn't benefit Blazor Server apps because Blazor Server app assemblies aren't downloaded to the client.
Project file configuration
Mark assemblies for lazy loading in the app's project file (.csproj) using the BlazorWebAssemblyLazyLoad item. Use the assembly name with the .dll extension. The Blazor framework prevents the assembly from loading at app launch.
<ItemGroup>
<BlazorWebAssemblyLazyLoad Include="{ASSEMBLY NAME}.dll" />
</ItemGroup>
The {ASSEMBLY NAME} placeholder is the name of the assembly. The .dll file extension is required.
Include one BlazorWebAssemblyLazyLoad item for each assembly. If an assembly has dependencies, include a BlazorWebAssemblyLazyLoad entry for each dependency.
Router component configuration
The Blazor framework automatically registers a singleton service for lazy loading assemblies in client-side Blazor WebAssembly apps†, LazyAssemblyLoader. The LazyAssemblyLoader.LoadAssembliesAsync method:
- Uses JS interop to fetch assemblies via a network call.
- Loads assemblies into the runtime executing on WebAssembly in the browser.
†Guidance for hosted Blazor WebAssembly solutions is covered in the Lazy load assemblies in a hosted Blazor WebAssembly solution section.
Blazor's Router component designates the assemblies that Blazor searches for routable components and is also responsible for rendering the component for the route where the user navigates. The Router component's OnNavigateAsync method is used in conjunction with lazy loading to load the correct assemblies for endpoints that a user requests.
Logic is implemented inside OnNavigateAsync to determine the assemblies to load with LazyAssemblyLoader. Options for how to structure the logic include:
- Conditional checks inside the OnNavigateAsync method.
- A lookup table that maps routes to assembly names, either injected into the component or implemented within the
@codeblock.
In the following example:
- The namespace for Microsoft.AspNetCore.Components.WebAssembly.Services is specified.
- The LazyAssemblyLoader service is injected (
AssemblyLoader). - The
{PATH}placeholder is the path where the list of assemblies should load. The example uses a conditional check for a single path that loads a single set of assemblies. - The
{LIST OF ASSEMBLIES}placeholder is the comma-separated list of assembly filename strings, including their.dllextensions (for example,"Assembly1.dll", "Assembly2.dll").
App.razor:
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject LazyAssemblyLoader AssemblyLoader
@inject ILogger<App> Logger
<Router AppAssembly="@typeof(Program).Assembly"
OnNavigateAsync="@OnNavigateAsync">
...
</Router>
@code {
private async Task OnNavigateAsync(NavigationContext args)
{
try
{
if (args.Path == "{PATH}")
{
var assemblies = await AssemblyLoader.LoadAssembliesAsync(
new[] { {LIST OF ASSEMBLIES} });
}
}
catch (Exception ex)
{
Logger.LogError("Error: {Message}", ex.Message);
}
}
}
Note
The preceding example doesn't show the contents of the Router component's Razor markup (...). For a demonstration with complete code, see the Complete example section of this article.
Assemblies that include routable components
When the list of assemblies includes routable components, the assembly list for a given path is passed to the Router component's AdditionalAssemblies collection.
In the following example:
- The List<Assembly> in
lazyLoadedAssembliespasses the assembly list to AdditionalAssemblies. The framework searches the assemblies for routes and updates the route collection if new routes are found. To access the Assembly type, the namespace for System.Reflection is included at the top of theApp.razorfile. - The
{PATH}placeholder is the path where the list of assemblies should load. The example uses a conditional check for a single path that loads a single set of assemblies. - The
{LIST OF ASSEMBLIES}placeholder is the comma-separated list of assembly filename strings, including their.dllextensions (for example,"Assembly1.dll", "Assembly2.dll").
App.razor:
@using System.Reflection
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject LazyAssemblyLoader AssemblyLoader
@inject ILogger<App> Logger
<Router AppAssembly="@typeof(Program).Assembly"
AdditionalAssemblies="@lazyLoadedAssemblies"
OnNavigateAsync="@OnNavigateAsync">
...
</Router>
@code {
private List<Assembly> lazyLoadedAssemblies = new();
private async Task OnNavigateAsync(NavigationContext args)
{
try
{
if (args.Path == "{PATH}")
{
var assemblies = await AssemblyLoader.LoadAssembliesAsync(
new[] { {LIST OF ASSEMBLIES} });
lazyLoadedAssemblies.AddRange(assemblies);
}
}
catch (Exception ex)
{
Logger.LogError("Error: {Message}", ex.Message);
}
}
}
Note
The preceding example doesn't show the contents of the Router component's Razor markup (...). For a demonstration with complete code, see the Complete example section of this article.
For more information, see ASP.NET Core Blazor routing and navigation.
User interaction with <Navigating> content
While loading assemblies, which can take several seconds, the Router component can indicate to the user that a page transition is occurring with the router's Navigating property.
For more information, see ASP.NET Core Blazor routing and navigation.
Handle cancellations in OnNavigateAsync
The NavigationContext object passed to the OnNavigateAsync callback contains a CancellationToken that's set when a new navigation event occurs. The OnNavigateAsync callback must throw when the cancellation token is set to avoid continuing to run the OnNavigateAsync callback on a outdated navigation.
For more information, see ASP.NET Core Blazor routing and navigation.
OnNavigateAsync events and renamed assembly files
The resource loader relies on the assembly names that are defined in the blazor.boot.json file. If assemblies are renamed, the assembly names used in an OnNavigateAsync callback and the assembly names in the blazor.boot.json file are out of sync.
To rectify this:
- Check to see if the app is running in the
Productionenvironment when determining which assembly names to use. - Store the renamed assembly names in a separate file and read from that file to determine what assembly name to use with the LazyAssemblyLoader service and OnNavigateAsync callback.
Lazy load assemblies in a hosted Blazor WebAssembly solution
The framework's lazy loading implementation supports lazy loading with prerendering in a hosted Blazor WebAssembly solution. During prerendering, all assemblies, including those marked for lazy loading, are assumed to be loaded. Manually register the LazyAssemblyLoader service in the Server project.
At the top of the Program.cs file of the Server project, add the namespace for Microsoft.AspNetCore.Components.WebAssembly.Services:
using Microsoft.AspNetCore.Components.WebAssembly.Services;
In Program.cs of the Server project, register the service:
builder.Services.AddScoped<LazyAssemblyLoader>();
Complete example
The demonstration in this section:
- Creates a robot controls assembly (
GrantImaharaRobotControls.dll) as a Razor class library (RCL) that includes aRobotcomponent (Robot.razorwith a route template of/robot). - Lazily loads the RCL's assembly to render its
Robotcomponent when the/robotURL is requested by the user.
Create a new ASP.NET Core class library project:
- Visual Studio: Create a solution > Create a new project > Razor Class Library. Name the project
GrantImaharaRobotControls. - Visual Studio Code/.NET CLI: Execute
dotnet new razorclasslib -o GrantImaharaRobotControlsfrom a command prompt. The-o|--outputoption creates a folder for the solution and names the projectGrantImaharaRobotControls.
- Visual Studio: Create a solution > Create a new project > Razor Class Library. Name the project
The example component presented later in this section uses a Blazor form. In the RCL project, add the
Microsoft.AspNetCore.Components.Formspackage to the project.Note
For guidance on adding packages to .NET apps, see the articles under Install and manage packages at Package consumption workflow (NuGet documentation). Confirm correct package versions at NuGet.org.
Create a
HandGestureclass in the RCL with aThumbUpmethod that hypothetically makes a robot perform a thumbs-up gesture. The method accepts an argument for the axis,LeftorRight, as anenum. The method returnstrueon success.HandGesture.cs:using Microsoft.Extensions.Logging; namespace GrantImaharaRobotControls { public static class HandGesture { public static bool ThumbUp(Axis axis, ILogger logger) { logger.LogInformation("Thumb up gesture. Axis: {Axis}", axis); // Code to make robot perform gesture return true; } } public enum Axis { Left, Right } }Add the following component to the root of the RCL project. The component permits the user to submit a left or right hand thumb-up gesture request.
Robot.razor:@page "/robot" @using Microsoft.AspNetCore.Components.Forms @using Microsoft.Extensions.Logging @inject ILogger<Robot> Logger <h1>Robot</h1> <EditForm Model="@robotModel" OnValidSubmit="@HandleValidSubmit"> <InputRadioGroup @bind-Value="robotModel.AxisSelection"> @foreach (var entry in (Axis[])Enum .GetValues(typeof(Axis))) { <InputRadio Value="@entry" /> <text> </text>@entry<br> } </InputRadioGroup> <button type="submit">Submit</button> </EditForm> <p> @message </p> @code { private RobotModel robotModel = new() { AxisSelection = Axis.Left }; private string? message; private void HandleValidSubmit() { Logger.LogInformation("HandleValidSubmit called"); var result = HandGesture.ThumbUp(robotModel.AxisSelection, Logger); message = $"ThumbUp returned {result} at {DateTime.Now}."; } public class RobotModel { public Axis AxisSelection { get; set; } } }
Create a Blazor WebAssembly app to demonstrate lazy loading of the RCL's assembly:
Create the Blazor WebAssembly app in Visual Studio, Visual Studio Code, or via a command prompt with the .NET CLI. Name the project
LazyLoadTest.Create a project reference for the
GrantImaharaRobotControlsRCL:- Visual Studio: Add the
GrantImaharaRobotControlsRCL project to the solution (Add > Existing Project). Select Add > Project Reference to add a project reference for theGrantImaharaRobotControlsRCL. - Visual Studio Code/.NET CLI: Execute
dotnet add reference {PATH}in a command shell from the project's folder. The{PATH}placeholder is the path to the RCL project.
- Visual Studio: Add the
Build and run the app. For the default page that loads the Index component (Pages/Index.razor), the developer tool's Network tab indicates that the RCL's assembly GrantImaharaRobotControls.dll is loaded. The Index component makes no use of the assembly, so loading the assembly is inefficient.

Configure the app to lazy load the GrantImaharaRobotControls.dll assembly:
Specify the RCL's assembly for lazy loading in the Blazor WebAssembly app's project file (
.csproj):<ItemGroup> <BlazorWebAssemblyLazyLoad Include="GrantImaharaRobotControls.dll" /> </ItemGroup>The following Router component demonstrates loading the
GrantImaharaRobotControls.dllassembly when the user navigates to/robot. Replace the app's defaultAppcomponent with the followingAppcomponent.During page transitions, a styled message is displayed to the user with the
<Navigating>element. For more information, see the User interaction with<Navigating>content section.The assembly is assigned to AdditionalAssemblies, which results in the router searching the assembly for routable components, where it finds the
Robotcomponent. TheRobotcomponent's route is added to the app's route collection. For more information, see the ASP.NET Core Blazor routing and navigation article and the Assemblies that include routable components section of this article.App.razor:@using System.Reflection @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.WebAssembly.Services @using Microsoft.Extensions.Logging @inject LazyAssemblyLoader AssemblyLoader @inject ILogger<App> Logger <Router AppAssembly="@typeof(Program).Assembly" AdditionalAssemblies="@lazyLoadedAssemblies" OnNavigateAsync="@OnNavigateAsync"> <Navigating> <div style="padding:20px;background-color:blue;color:white"> <p>Loading the requested page…</p> </div> </Navigating> <Found Context="routeData"> <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> </Found> <NotFound> <LayoutView Layout="@typeof(MainLayout)"> <p>Sorry, there's nothing at this address.</p> </LayoutView> </NotFound> </Router> @code { private List<Assembly> lazyLoadedAssemblies = new(); private async Task OnNavigateAsync(NavigationContext args) { try { if (args.Path == "robot") { var assemblies = await AssemblyLoader.LoadAssembliesAsync( new[] { "GrantImaharaRobotControls.dll" }); lazyLoadedAssemblies.AddRange(assemblies); } } catch (Exception ex) { Logger.LogError("Error: {Message}", ex.Message); } } }
Build and run the app again. For the default page that loads the Index component (Pages/Index.razor), the developer tool's Network tab indicates that the RCL's assembly (GrantImaharaRobotControls.dll) does not load for the Index component:

If the Robot component from the RCL is requested at https://localhost:5001/robot, the GrantImaharaRobotControls.dll assembly is loaded and the Robot component is rendered:

Troubleshoot
- If unexpected rendering occurs, such as rendering a component from a previous navigation, confirm that the code throws if the cancellation token is set.
- If assemblies configured for lazy loading unexpectedly load at app start, check that the assembly is marked for lazy loading in the project file.
Note
A known issue exists for loading types from a lazily-loaded assembly. For more information, see Blazor WebAssembly lazy loading assemblies not working when using @ref attribute in the component (dotnet/aspnetcore #29342).
Additional resources
Blazor WebAssembly app startup performance can be improved by waiting to load app assemblies until the assemblies are required, which is called lazy loading.
This article's initial sections cover the app configuration. For a working demonstration, see the Complete example section at the end of this article.
Note
Assembly lazy loading doesn't benefit Blazor Server apps because Blazor Server app assemblies aren't downloaded to the client.
Project file configuration
Mark assemblies for lazy loading in the app's project file (.csproj) using the BlazorWebAssemblyLazyLoad item. Use the assembly name with the .dll extension. The Blazor framework prevents the assembly from loading at app launch.
<ItemGroup>
<BlazorWebAssemblyLazyLoad Include="{ASSEMBLY NAME}.dll" />
</ItemGroup>
The {ASSEMBLY NAME} placeholder is the name of the assembly. The .dll file extension is required.
Include one BlazorWebAssemblyLazyLoad item for each assembly. If an assembly has dependencies, include a BlazorWebAssemblyLazyLoad entry for each dependency.
Router component configuration
The Blazor framework automatically registers a singleton service for lazy loading assemblies in client-side Blazor WebAssembly apps†, LazyAssemblyLoader. The LazyAssemblyLoader.LoadAssembliesAsync method:
- Uses JS interop to fetch assemblies via a network call.
- Loads assemblies into the runtime executing on WebAssembly in the browser.
†Guidance for hosted Blazor WebAssembly solutions is covered in the Lazy load assemblies in a hosted Blazor WebAssembly solution section.
Blazor's Router component designates the assemblies that Blazor searches for routable components and is also responsible for rendering the component for the route where the user navigates. The Router component's OnNavigateAsync method is used in conjunction with lazy loading to load the correct assemblies for endpoints that a user requests.
Logic is implemented inside OnNavigateAsync to determine the assemblies to load with LazyAssemblyLoader. Options for how to structure the logic include:
- Conditional checks inside the OnNavigateAsync method.
- A lookup table that maps routes to assembly names, either injected into the component or implemented within the
@codeblock.
In the following example:
- The namespace for Microsoft.AspNetCore.Components.WebAssembly.Services is specified.
- The LazyAssemblyLoader service is injected (
AssemblyLoader). - The
{PATH}placeholder is the path where the list of assemblies should load. The example uses a conditional check for a single path that loads a single set of assemblies. - The
{LIST OF ASSEMBLIES}placeholder is the comma-separated list of assembly filename strings, including their.dllextensions (for example,"Assembly1.dll", "Assembly2.dll").
App.razor:
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject LazyAssemblyLoader AssemblyLoader
@inject ILogger<App> Logger
<Router AppAssembly="@typeof(Program).Assembly"
OnNavigateAsync="@OnNavigateAsync">
...
</Router>
@code {
private async Task OnNavigateAsync(NavigationContext args)
{
try
{
if (args.Path == "{PATH}")
{
var assemblies = await AssemblyLoader.LoadAssembliesAsync(
new[] { {LIST OF ASSEMBLIES} });
}
}
catch (Exception ex)
{
Logger.LogError("Error: {Message}", ex.Message);
}
}
}
Note
The preceding example doesn't show the contents of the Router component's Razor markup (...). For a demonstration with complete code, see the Complete example section of this article.
Note
With the release of ASP.NET Core 5.0.1 and for any additional 5.x releases, the Router component includes the PreferExactMatches parameter set to @true. For more information, see Migrate from ASP.NET Core 3.1 to 5.0.
Assemblies that include routable components
When the list of assemblies includes routable components, the assembly list for a given path is passed to the Router component's AdditionalAssemblies collection.
In the following example:
- The List<Assembly> in
lazyLoadedAssembliespasses the assembly list to AdditionalAssemblies. The framework searches the assemblies for routes and updates the route collection if new routes are found. To access the Assembly type, the namespace for System.Reflection is included at the top of theApp.razorfile. - The
{PATH}placeholder is the path where the list of assemblies should load. The example uses a conditional check for a single path that loads a single set of assemblies. - The
{LIST OF ASSEMBLIES}placeholder is the comma-separated list of assembly filename strings, including their.dllextensions (for example,"Assembly1.dll", "Assembly2.dll").
App.razor:
@using System.Reflection
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject LazyAssemblyLoader AssemblyLoader
@inject ILogger<App> Logger
<Router AppAssembly="@typeof(Program).Assembly"
AdditionalAssemblies="@lazyLoadedAssemblies"
OnNavigateAsync="@OnNavigateAsync">
...
</Router>
@code {
private List<Assembly> lazyLoadedAssemblies = new();
private async Task OnNavigateAsync(NavigationContext args)
{
try
{
if (args.Path == "{PATH}")
{
var assemblies = await AssemblyLoader.LoadAssembliesAsync(
new[] { {LIST OF ASSEMBLIES} });
lazyLoadedAssemblies.AddRange(assemblies);
}
}
catch (Exception ex)
{
Logger.LogError("Error: {Message}", ex.Message);
}
}
}
Note
The preceding example doesn't show the contents of the Router component's Razor markup (...). For a demonstration with complete code, see the Complete example section of this article.
Note
With the release of ASP.NET Core 5.0.1 and for any additional 5.x releases, the Router component includes the PreferExactMatches parameter set to @true. For more information, see Migrate from ASP.NET Core 3.1 to 5.0.
For more information, see ASP.NET Core Blazor routing and navigation.
User interaction with <Navigating> content
While loading assemblies, which can take several seconds, the Router component can indicate to the user that a page transition is occurring with the router's Navigating property.
For more information, see ASP.NET Core Blazor routing and navigation.
Handle cancellations in OnNavigateAsync
The NavigationContext object passed to the OnNavigateAsync callback contains a CancellationToken that's set when a new navigation event occurs. The OnNavigateAsync callback must throw when the cancellation token is set to avoid continuing to run the OnNavigateAsync callback on a outdated navigation.
For more information, see ASP.NET Core Blazor routing and navigation.
OnNavigateAsync events and renamed assembly files
The resource loader relies on the assembly names that are defined in the blazor.boot.json file. If assemblies are renamed, the assembly names used in an OnNavigateAsync callback and the assembly names in the blazor.boot.json file are out of sync.
To rectify this:
- Check to see if the app is running in the
Productionenvironment when determining which assembly names to use. - Store the renamed assembly names in a separate file and read from that file to determine what assembly name to use with the LazyAssemblyLoader service and OnNavigateAsync callback.
Lazy load assemblies in a hosted Blazor WebAssembly solution
The framework's lazy loading implementation supports lazy loading with prerendering in a hosted Blazor WebAssembly solution. During prerendering, all assemblies, including those marked for lazy loading, are assumed to be loaded. Manually register the LazyAssemblyLoader service in the Server project.
At the top of the Startup.cs file of the Server project, add the namespace for Microsoft.AspNetCore.Components.WebAssembly.Services:
using Microsoft.AspNetCore.Components.WebAssembly.Services;
In the Startup.ConfigureServices method (Startup.cs) of the Server project, register the service:
services.AddScoped<LazyAssemblyLoader>();
Complete example
The demonstration in this section:
- Creates a robot controls assembly (
GrantImaharaRobotControls.dll) as a Razor class library (RCL) that includes aRobotcomponent (Robot.razorwith a route template of/robot). - Lazily loads the RCL's assembly to render its
Robotcomponent when the/robotURL is requested by the user.
Create a new ASP.NET Core class library project:
- Visual Studio: Create a solution > Create a new project > Razor Class Library. Name the project
GrantImaharaRobotControls. - Visual Studio Code/.NET CLI: Execute
dotnet new razorclasslib -o GrantImaharaRobotControlsfrom a command prompt. The-o|--outputoption creates a folder for the solution and names the projectGrantImaharaRobotControls.
- Visual Studio: Create a solution > Create a new project > Razor Class Library. Name the project
The example component presented later in this section uses a Blazor form. In the RCL project, add the
Microsoft.AspNetCore.Components.Formspackage to the project.Note
For guidance on adding packages to .NET apps, see the articles under Install and manage packages at Package consumption workflow (NuGet documentation). Confirm correct package versions at NuGet.org.
Create a
HandGestureclass in the RCL with aThumbUpmethod that hypothetically makes a robot perform a thumbs-up gesture. The method accepts an argument for the axis,LeftorRight, as anenum. The method returnstrueon success.HandGesture.cs:using Microsoft.Extensions.Logging; namespace GrantImaharaRobotControls { public static class HandGesture { public static bool ThumbUp(Axis axis, ILogger logger) { logger.LogInformation("Thumb up gesture. Axis: {Axis}", axis); // Code to make robot perform gesture return true; } } public enum Axis { Left, Right } }Add the following component to the root of the RCL project. The component permits the user to submit a left or right hand thumb-up gesture request.
Robot.razor:@page "/robot" @using Microsoft.AspNetCore.Components.Forms @using Microsoft.Extensions.Logging @inject ILogger<Robot> Logger <h1>Robot</h1> <EditForm Model="@robotModel" OnValidSubmit="@HandleValidSubmit"> <InputRadioGroup @bind-Value="robotModel.AxisSelection"> @foreach (var entry in (Axis[])Enum .GetValues(typeof(Axis))) { <InputRadio Value="@entry" /> <text> </text>@entry<br> } </InputRadioGroup> <button type="submit">Submit</button> </EditForm> <p> @message </p> @code { private RobotModel robotModel = new() { AxisSelection = Axis.Left }; private string message; private void HandleValidSubmit() { Logger.LogInformation("HandleValidSubmit called"); var result = HandGesture.ThumbUp(robotModel.AxisSelection, Logger); message = $"ThumbUp returned {result} at {DateTime.Now}."; } public class RobotModel { public Axis AxisSelection { get; set; } } }
Create a Blazor WebAssembly app to demonstrate lazy loading of the RCL's assembly:
Create the Blazor WebAssembly app in Visual Studio, Visual Studio Code, or via a command prompt with the .NET CLI. Name the project
LazyLoadTest.Create a project reference for the
GrantImaharaRobotControlsRCL:- Visual Studio: Add the
GrantImaharaRobotControlsRCL project to the solution (Add > Existing Project). Select Add > Project Reference to add a project reference for theGrantImaharaRobotControlsRCL. - Visual Studio Code/.NET CLI: Execute
dotnet add reference {PATH}in a command shell from the project's folder. The{PATH}placeholder is the path to the RCL project.
- Visual Studio: Add the
Build and run the app. For the default page that loads the Index component (Pages/Index.razor), the developer tool's Network tab indicates that the RCL's assembly GrantImaharaRobotControls.dll is loaded. The Index component makes no use of the assembly, so loading the assembly is inefficient.

Configure the app to lazy load the GrantImaharaRobotControls.dll assembly:
Specify the RCL's assembly for lazy loading in the Blazor WebAssembly app's project file (
.csproj):<ItemGroup> <BlazorWebAssemblyLazyLoad Include="GrantImaharaRobotControls.dll" /> </ItemGroup>The following Router component demonstrates loading the
GrantImaharaRobotControls.dllassembly when the user navigates to/robot. Replace the app's defaultAppcomponent with the followingAppcomponent.During page transitions, a styled message is displayed to the user with the
<Navigating>element. For more information, see the User interaction with<Navigating>content section.The assembly is assigned to AdditionalAssemblies, which results in the router searching the assembly for routable components, where it finds the
Robotcomponent. TheRobotcomponent's route is added to the app's route collection. For more information, see the ASP.NET Core Blazor routing and navigation article and the Assemblies that include routable components section of this article.App.razor:@using System.Reflection @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.WebAssembly.Services @using Microsoft.Extensions.Logging @inject LazyAssemblyLoader AssemblyLoader @inject ILogger<App> Logger <Router AppAssembly="@typeof(Program).Assembly" AdditionalAssemblies="@lazyLoadedAssemblies" OnNavigateAsync="@OnNavigateAsync"> <Navigating> <div style="padding:20px;background-color:blue;color:white"> <p>Loading the requested page…</p> </div> </Navigating> <Found Context="routeData"> <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> </Found> <NotFound> <LayoutView Layout="@typeof(MainLayout)"> <p>Sorry, there's nothing at this address.</p> </LayoutView> </NotFound> </Router> @code { private List<Assembly> lazyLoadedAssemblies = new(); private async Task OnNavigateAsync(NavigationContext args) { try { if (args.Path == "robot") { var assemblies = await AssemblyLoader.LoadAssembliesAsync( new[] { "GrantImaharaRobotControls.dll" }); lazyLoadedAssemblies.AddRange(assemblies); } } catch (Exception ex) { Logger.LogError("Error: {Message}", ex.Message); } } }Note
With the release of ASP.NET Core 5.0.1 and for any additional 5.x releases, the
Routercomponent includes thePreferExactMatchesparameter set to@true. For more information, see Migrate from ASP.NET Core 3.1 to 5.0.
Build and run the app again. For the default page that loads the Index component (Pages/Index.razor), the developer tool's Network tab indicates that the RCL's assembly (GrantImaharaRobotControls.dll) does not load for the Index component:

If the Robot component from the RCL is requested at https://localhost:5001/robot, the GrantImaharaRobotControls.dll assembly is loaded and the Robot component is rendered:

Troubleshoot
- If unexpected rendering occurs, such as rendering a component from a previous navigation, confirm that the code throws if the cancellation token is set.
- If assemblies configured for lazy loading unexpectedly load at app start, check that the assembly is marked for lazy loading in the project file.
Note
A known issue exists for loading types from a lazily-loaded assembly. For more information, see Blazor WebAssembly lazy loading assemblies not working when using @ref attribute in the component (dotnet/aspnetcore #29342).
Additional resources
Feedback
Issottometti u ara feedback għal