In this article, we’ll examine how to implement lazy loading using Blazor WebAssembly. We can speed up the startup of our Blazor WebAssembly application by delaying the download of resources we don’t currently require. For instance, downloading all the files pertaining to products, authentication, and other things is useless if we have a large Blazor WebAssembly application and our users only want to view the home or contact pages. The program will only download these resources if the user specifically requests them when lazy loading is enabled.
Setup Blazor WASM Project
Open the Visual Studio and search for Blazor App. Click on the Next button,
Define the project name, path, and solution name. Click on the Create button,
After that a new window will pop up to choose the target framework (.Net 6.0) from the dropdown and make sure to select the Blazor server App and in the Advanced section “Configure the Https” is checked.
Blazor Wasm Standard Workflow
If we now launch our application, access the Dev Tools window (F12), select the Application tab, and check the cache:
Although we are still on the Home page and have not navigated anywhere else, we can see that our BlazorWasmLazyLoading.dll file has been downloaded and cached, which is typical. However, it also suggests that all of the components in this DLL have been downloaded. Of course, for small apps like this one, this is not a problem. However, it could significantly speed up downloads for a more complex application. So let’s work out a way to prevent it.
Updating the primary project with new packages
We’re going to use the Syncfusion Libraries in this article to work with the idea of lazy loading, so create a new Razor class library project called Weather and empty it out except for the _Imports.razor
file. Additionally, this project needs to be referenced from the main one.
From the right-click menu of the project, choose Manage NuGet Packages.
Afterward, use the word Syncfusion. Blazor, locate, and set up the proper Syncfusion.Blazor. Blazor NuGet packages. In this location, Syncfusion has been installed. The program makes use of the NuGet packages Syncfusion and Blazor Buttons.Blazor.Calendars. Look at the illustration below.
Configure the Syncfusion Blazor Service in Program.cs file as per the below code.
using LazyLoading; using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Syncfusion.Blazor; var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add<App>("#app"); builder.RootComponents.Add<HeadOutlet>("head::after"); builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); builder.Services.AddSyncfusionBlazor(); await builder.Build().RunAsync();
Implementation Lazy Loading
In order to use Blazor WebAssembly’s Lazy Loading feature, we must first make a change to the main project file. Therefore, from the context menu, right-click on the BlazorWasmLazyLoading project and choose EditProjectFile:
LazyLoading.csproj
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly"> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.1" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.1" PrivateAssets="all" /> <PackageReference Include="Syncfusion.Blazor.Buttons" Version="19.4.0.48" /> <PackageReference Include="Syncfusion.Blazor.Calendars" Version="19.4.0.48" /> <PackageReference Include="Syncfusion.Blazor.Charts" Version="19.4.0.48" /> <PackageReference Include="Syncfusion.Blazor.Data" Version="19.4.0.48" /> <PackageReference Include="Syncfusion.Blazor.DropDowns" Version="19.4.0.48" /> <PackageReference Include="Syncfusion.Blazor.Grid" Version="19.4.0.48" /> <PackageReference Include="Syncfusion.Blazor.Lists" Version="19.4.0.48" /> <PackageReference Include="Syncfusion.Blazor.Navigations" Version="19.4.0.48" /> <PackageReference Include="Syncfusion.Blazor.Notifications" Version="19.4.0.48" /> <PackageReference Include="Syncfusion.Blazor.Popups" Version="19.4.0.48" /> <PackageReference Include="Syncfusion.Blazor.Spinner" Version="19.4.0.48" /> <PackageReference Include="Syncfusion.Blazor.SplitButtons" Version="19.4.0.48" /> </ItemGroup> <ItemGroup> <BlazorWebAssemblyLazyLoad Include="Syncfusion.Blazor.Buttons.dll" /> <BlazorWebAssemblyLazyLoad Include="Syncfusion.Blazor.Calendars.dll" /> <BlazorWebAssemblyLazyLoad Include="Syncfusion.Blazor.Charts.dll" /> <BlazorWebAssemblyLazyLoad Include="Syncfusion.Blazor.Data.dll" /> <BlazorWebAssemblyLazyLoad Include="Syncfusion.Blazor.DropDowns.dll" /> <BlazorWebAssemblyLazyLoad Include="Syncfusion.Blazor.Grids.dll" /> <BlazorWebAssemblyLazyLoad Include="Syncfusion.Blazor.Lists.dll" /> <BlazorWebAssemblyLazyLoad Include="Syncfusion.Blazor.Navigations.dll" /> <BlazorWebAssemblyLazyLoad Include="Syncfusion.Blazor.Notifications.dll" /> <BlazorWebAssemblyLazyLoad Include="Syncfusion.Blazor.Popups.dll" /> <BlazorWebAssemblyLazyLoad Include="Syncfusion.Blazor.Spinner.dll" /> <BlazorWebAssemblyLazyLoad Include="Syncfusion.Blazor.SplitButtons.dll" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\Sample\Sample.csproj" /> </ItemGroup> <ItemGroup> <BlazorWebAssemblyLazyLoad Include="Sample.dll" /> </ItemGroup> </Project>
Modifying App.razor File to Load the Required DLL
We import the required utilizing directives before injecting the AssemblyLoader to load our assembly. The OnNavigateAsync event callback in the Router component is then given the OnNavigateAsync method. The OnNavigateAsync event callback is invoked just before switching to a new page. The AdditionalAssemblies property is also set to true. This attribute instructs our program to use additional assemblies to search for components that match the correct URIs.
In the @code section, we create the _lazyLoadedAssemblies private list of assemblies and the OnNavigateAsync method with the NavigationContext parameter. We check the currently required route inside the procedure using the context argument. If the fetch data route—the route of our FetchData component—matches, we use the LoadAssembliesAsync method to load the assemblies.
@using System.Reflection; @using Microsoft.AspNetCore.Components.Routing; @using Microsoft.AspNetCore.Components.WebAssembly.Services; @inject LazyAssemblyLoader assemblyLoader; <Router AppAssembly="@typeof(App).Assembly" PreferExactMatches="@true" AdditionalAssemblies="@lazyLoadedAssemblies" OnNavigateAsync="@OnNavigateAsync"> <Found Context="routeData"> <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> <FocusOnNavigate RouteData="@routeData" Selector="h1" /> </Found> <NotFound> <PageTitle>Not found</PageTitle> <LayoutView Layout="@typeof(MainLayout)"> <p role="alert">Sorry, there's nothing at this address.</p> </LayoutView> </NotFound> </Router> @code { private List<Assembly> lazyLoadedAssemblies = new List<Assembly>(); private async Task OnNavigateAsync(NavigationContext args) { try { if (args.Path.StartsWith("fetchdata")) { var assemblies = await assemblyLoader.LoadAssembliesAsync(new[] { "Sample.dll" }); assemblies = await assemblyLoader.LoadAssembliesAsync(new[] { "Syncfusion.Blazor.Buttons.dll" }); assemblies = await assemblyLoader.LoadAssembliesAsync(new[] { "Syncfusion.Blazor.Charts.dll" }); assemblies = await assemblyLoader.LoadAssembliesAsync(new[] { "Syncfusion.Blazor.Data.dll" }); assemblies = await assemblyLoader.LoadAssembliesAsync(new[] { "Syncfusion.Blazor.DropDowns.dll" }); assemblies = await assemblyLoader.LoadAssembliesAsync(new[] { "Syncfusion.Blazor.Grid.dll" }); lazyLoadedAssemblies.AddRange(assemblies); } if(args.Path.StartsWith("counter")) { var assemblies = await assemblyLoader.LoadAssembliesAsync(new[] { "Syncfusion.Blazor.Calendars.dll" }); assemblies = await assemblyLoader.LoadAssembliesAsync(new[] { "Syncfusion.Blazor.Buttons.dll" }); assemblies = await assemblyLoader.LoadAssembliesAsync(new[] { "Syncfusion.Blazor.Lists.dll" }); assemblies = await assemblyLoader.LoadAssembliesAsync(new[] { "Syncfusion.Blazor.Navigations.dll" }); assemblies = await assemblyLoader.LoadAssembliesAsync(new[] { "Syncfusion.Blazor.Notifications.dll" }); assemblies = await assemblyLoader.LoadAssembliesAsync(new[] { "Syncfusion.Blazor.Popups.dll" }); assemblies = await assemblyLoader.LoadAssembliesAsync(new[] { "Syncfusion.Blazor.Spinner.dll" }); assemblies = await assemblyLoader.LoadAssembliesAsync(new[] { "Syncfusion.Blazor.SplitButtons.dll" }); lazyLoadedAssemblies.AddRange(assemblies); } } catch (Exception ex) { } } }
Keep in mind that we won’t be able to locate the downloaded Sample.dll if we launch the app and search the cache. However, if we visit the FetchData page and the counter page, we can see the content of each page as well as the dependencies that have been downloaded.
Counter page
Conclusion
Currently, we are aware of how to load various dependencies solely when necessary using Blazor WebAssembly’s lazy loading feature. As was already mentioned, this is a great feature because it speeds up the loading of our application.
All there is to it is that!