Événement
Championnats du monde Power BI DataViz
14 févr., 16 h - 31 mars, 16 h
Avec 4 chances d’entrer, vous pourriez gagner un package de conférence et le rendre à la Live Grand Finale à Las Vegas
En savoir plusCe navigateur n’est plus pris en charge.
Effectuez une mise à niveau vers Microsoft Edge pour tirer parti des dernières fonctionnalités, des mises à jour de sécurité et du support technique.
Note
Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 9 de cet article.
Avertissement
Cette version d’ASP.NET Core n’est plus prise en charge. Pour plus d’informations, consultez la stratégie de support .NET et .NET Core. Pour la version actuelle, consultez la version .NET 9 de cet article.
Important
Ces informations portent sur la préversion du produit, qui est susceptible d’être en grande partie modifié avant sa commercialisation. Microsoft n’offre aucune garantie, expresse ou implicite, concernant les informations fournies ici.
Pour la version actuelle, consultez la version .NET 9 de cet article.
Les performances de démarrage de l’application Blazor WebAssembly peuvent être améliorées en chargeant les assemblys d’application créés par le développeur uniquement s’ils sont requis. Cela s’appelle le chargement différé.
Les premières sections de cet article portent sur la configuration des applications. Pour une démonstration pratique, consultez la section Exemple complet à la fin de cet article.
Cet article s’applique uniquement aux applications Blazor WebAssembly. Le chargement différé d’assembly ne bénéficie pas aux applications côté serveur, car les applications rendues par le serveur ne téléchargent pas d’assemblys sur le client.
Le chargement différé ne doit pas être utilisé pour les principaux assemblys de CLR, qui peuvent être supprimés lors de la publication et indisponibles sur le client lorsque l’application se charge.
Les fichiers d’assembly utilisent le format d’empaquetage Webcil pour les assemblies .NET avec une extension de fichier .wasm
.
Tout au long de l’article, l’espace réservé {FILE EXTENSION}
représente « wasm
».
Les fichiers d’assembly sont basés sur des bibliothèques de liens dynamiques (Dynamic-Link Libraries/DLL) avec une extension de fichier .dll
.
Tout au long de l’article, l’espace réservé {FILE EXTENSION}
représente « dll
».
Marquez les assemblys pour le chargement différé dans le fichier projet (.csproj
) de l’application en utilisant l’élément BlazorWebAssemblyLazyLoad
. Utilisez le nom de l’assembly avec l’extension de fichier. Le framework Blazor empêche le chargement de l’assembly au lancement de l’application.
<ItemGroup>
<BlazorWebAssemblyLazyLoad Include="{ASSEMBLY NAME}.{FILE EXTENSION}" />
</ItemGroup>
L’espace réservé {ASSEMBLY NAME}
est le nom de l’assembly et l’espace réservé {FILE EXTENSION}
est l’extension de fichier. L’extension de fichier est obligatoire.
Incluez un élément BlazorWebAssemblyLazyLoad
pour chaque assembly. Si un assembly possède des dépendances, incluez une entrée BlazorWebAssemblyLazyLoad
pour chaque dépendance.
L’infrastructure Blazor enregistre automatiquement un service singleton pour le chargement différé des assemblys dans les applications Blazor WebAssembly coté client, LazyAssemblyLoader. La méthode LazyAssemblyLoader.LoadAssembliesAsync :
Note
L’aide concernant les solutions Blazor WebAssembly hébergées se trouve dans la section Charger des assemblys en mode différé dans une solution Blazor WebAssembly hébergée.
Le composant Router de Blazor désigne les assemblys dans lesquels Blazor recherche des composants routables. Il est également responsable du rendu du composant pour la route empruntée par l’utilisateur. La méthode OnNavigateAsync
du composant Router est utilisée conjointement avec le chargement différé pour charger les assemblys appropriés pour les points de terminaison demandés par un utilisateur.
La logique est implémentée dans OnNavigateAsync pour déterminer quels assemblys charger avec LazyAssemblyLoader. Les options de structuration de la logique sont les suivantes :
@code
.Dans l’exemple suivant :
AssemblyLoader
).{PATH}
est le chemin où la liste d’assembly doit se charger. L’exemple utilise une vérification conditionnelle qui contrôle qu’un seul chemin charge un ensemble unique d’assemblys.{LIST OF ASSEMBLIES}
est la liste séparée par des virgules des chaînes de nom de fichier d’assembly, avec leurs extensions de fichier (par exemple, "Assembly1.{FILE EXTENSION}", "Assembly2.{FILE EXTENSION}"
).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(App).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);
}
}
}
@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
L’exemple précédent ne présente pas le contenu de la balise Razor (...
) du composant Router. Pour une démonstration avec le code complet, consultez la section Exemple complet de cet article.
Note
Depuis le lancement d’ASP.NET Core 5.0.1 et pour les éventuelles versions 5.x supplémentaires, le composant Router
comprend le paramètre PreferExactMatches
, qui est défini sur @true
. Pour plus d’informations, consultez Migrer de ASP.NET Core 3.1 vers 5.0.
Quand la liste d’assemblys inclut des composants routables, la liste d’assemblys d’un chemin donné est transmise à la collection AdditionalAssemblies du composant Router.
Dans l’exemple suivant :
lazyLoadedAssemblies
transmet la liste d’assemblys à AdditionalAssemblies. Le framework recherche des routes dans les assemblys et met à jour la collection de routes s’il en trouve de nouvelles. Pour accéder au type Assembly, l’espace de noms pour System.Reflection est inclus en haut du fichier App.razor
.{PATH}
est le chemin où la liste d’assembly doit se charger. L’exemple utilise une vérification conditionnelle qui contrôle qu’un seul chemin charge un ensemble unique d’assemblys.{LIST OF ASSEMBLIES}
est la liste séparée par des virgules des chaînes de nom de fichier d’assembly, avec leurs extensions de fichier (par exemple, "Assembly1.{FILE EXTENSION}", "Assembly2.{FILE EXTENSION}"
).App.razor
:
@using System.Reflection
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject ILogger<App> Logger
@inject LazyAssemblyLoader AssemblyLoader
<Router AppAssembly="typeof(App).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);
}
}
}
@using System.Reflection
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject ILogger<App> Logger
@inject LazyAssemblyLoader AssemblyLoader
<Router AppAssembly="typeof(Program).Assembly"
AdditionalAssemblies="lazyLoadedAssemblies"
OnNavigateAsync="OnNavigateAsync">
...
</Router>
@code {
private List<Assembly> lazyLoadedAssemblies = new List<Assembly>();
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
L’exemple précédent ne présente pas le contenu de la balise Razor (...
) du composant Router. Pour une démonstration avec le code complet, consultez la section Exemple complet de cet article.
Note
Depuis le lancement d’ASP.NET Core 5.0.1 et pour les éventuelles versions 5.x supplémentaires, le composant Router
comprend le paramètre PreferExactMatches
, qui est défini sur @true
. Pour plus d’informations, consultez Migrer de ASP.NET Core 3.1 vers 5.0.
Pour plus d’informations, consultez Routage et navigation ASP.NET Core Blazor.
Pendant le chargement d’assemblys, ce qui peut prendre plusieurs secondes, le composant Router peut indiquer à l’utilisateur qu’une transition de page se produit avec la propriété Navigating du routeur.
Pour plus d’informations, consultez Routage et navigation ASP.NET Core Blazor.
L’objet NavigationContext passé au rappel de OnNavigateAsync contient un CancellationToken qui est défini quand un nouvel événement de navigation se produit. Le rappel OnNavigateAsync doit se lever une exception quand le jeton d’annulation est défini pour éviter de continuer à exécuter le rappel OnNavigateAsync dans une navigation obsolète.
Pour plus d’informations, consultez Routage et navigation ASP.NET Core Blazor.
Le chargeur de ressources se fie aux noms d’assembly définis dans le fichier blazor.boot.json
. Si des assemblys sont renommés, les noms d’assembly utilisés dans un rappel OnNavigateAsync et les noms d’assembly présents dans le fichier blazor.boot.json
ne sont pas synchronisés.
Pour rectifier cela :
Production
au moment de déterminer les noms d’assembly à utiliser.L’implémentation du chargement différé du framework prend en charge le chargement différé avec prérendu dans une solution Blazor WebAssembly hébergée. Pendant le prérendu, tous les assemblys, y compris ceux marqués pour le chargement différé, sont supposés être chargés. Inscrivez manuellement le service LazyAssemblyLoader dans le projet Server.
Dans la partie supérieure du fichier Program.cs
du projet Server, ajoutez l’espace de noms pour Microsoft.AspNetCore.Components.WebAssembly.Services :
using Microsoft.AspNetCore.Components.WebAssembly.Services;
Dans le fichier Program.cs
du projet Server, inscrivez le service :
builder.Services.AddScoped<LazyAssemblyLoader>();
Dans la partie supérieure du fichier Startup.cs
du projet Server, ajoutez l’espace de noms pour Microsoft.AspNetCore.Components.WebAssembly.Services :
using Microsoft.AspNetCore.Components.WebAssembly.Services;
Dans le fichier Startup.ConfigureServices
(Startup.cs
) du projet Server, inscrivez le service :
services.AddScoped<LazyAssemblyLoader>();
La démonstration de cette section effectue les opérations suivantes :
GrantImaharaRobotControls.{FILE EXTENSION}
) en tant que bibliothèque de classes Razor (RCL) qui inclut un composant Robot
(Robot.razor
avec un modèle de route /robot
).Robot
quand l’URL /robot
est demandée par l’utilisateur.Créer une application autonome Blazor WebAssembly pour illustrer le chargement différé de l’assembly d’une bibliothèque de classes Razor. Nommez le projet LazyLoadTest
.
Ajouter un projet de bibliothèque de classes ASP.NET Core à la solution :
GrantImaharaRobotControls
. Ne cochez pas la case Prendre en charge les pages et les vues.dotnet new razorclasslib -o GrantImaharaRobotControls
depuis une invite de commandes. L’option -o|--output
crée un dossier et nomme le projet GrantImaharaRobotControls
.L’exemple de composant présenté plus loin dans cette section utilise un formulaire Blazor. Dans le projet RCL, ajoutez le package Microsoft.AspNetCore.Components.Forms
au projet.
Note
Pour obtenir des conseils sur l’ajout de packages à des applications .NET, consultez les articles figurant sous Installer et gérer des packages dans Flux de travail de la consommation des packages (documentation NuGet). Vérifiez les versions du package sur NuGet.org.
Créez une classe HandGesture
dans la RCL avec une méthode ThumbUp
qui est censée faire lever le pouce à un robot. La méthode accepte un argument pour l’axe, Left
ou Right
, en tant que enum
. La méthode retourne true
en cas de réussite.
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 }
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 }
}
Ajoutez le composant suivant à la racine du projet RCL. Le composant permet à l’utilisateur d’envoyer une demande de lever de pouce gauche ou droit.
Robot.razor
:
@page "/robot"
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.Extensions.Logging
@inject ILogger<Robot> Logger
<h1>Robot</h1>
<EditForm FormName="RobotForm" Model="robotModel" OnValidSubmit="HandleValidSubmit">
<InputRadioGroup @bind-Value="robotModel.AxisSelection">
@foreach (var entry in Enum.GetValues<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; }
}
}
@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 Enum.GetValues<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; }
}
}
@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 RobotModel() { 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; }
}
}
Dans le projet LazyLoadTest
, créez une référence de projet pour la RCL GrantImaharaRobotControls
:
LazyLoadTest
, puis sélectionnez Ajouter>Référence de projet pour ajouter une référence de projet pour la RCL GrantImaharaRobotControls
.dotnet add reference {PATH}
dans un interpréteur de commandes depuis le dossier du projet. L’espace réservé {PATH}
est le chemin du projet RCL.Spécifiez l’assembly de la RCL pour le chargement différé dans le fichier projet (.csproj
) de l’application LazyLoadTest
:
<ItemGroup>
<BlazorWebAssemblyLazyLoad Include="GrantImaharaRobotControls.{FILE EXTENSION}" />
</ItemGroup>
Le composant suivant Router illustre le chargement de l’assembly GrantImaharaRobotControls.{FILE EXTENSION}
quand l’utilisateur accède à /robot
. Remplacez le composant par défaut App
de l’application par le composant App
suivant.
Pendant les transitions de page, un message stylise est présenté à l’utilisateur avec l’élément <Navigating>
. Pour plus d’informations, consultez la section Interaction utilisateur avec le contenu <Navigating>
.
L’assembly est affecté à AdditionalAssemblies, ce qui amène le routeur à rechercher des composants routables dans l’assembly, où il trouve le composant Robot
. La route du composant Robot
est ajoutée à la collection de routes de l’application. Pour plus d’informations, consultez l’article Routage et navigation Blazor ASP.NET Core et la section Assemblys qui incluent des composants routables de cet article.
App.razor
:
@using System.Reflection
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject ILogger<App> Logger
@inject LazyAssemblyLoader AssemblyLoader
<Router AppAssembly="typeof(App).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.{FILE EXTENSION}" });
lazyLoadedAssemblies.AddRange(assemblies);
}
}
catch (Exception ex)
{
Logger.LogError("Error: {Message}", ex.Message);
}
}
}
@using System.Reflection
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject ILogger<App> Logger
@inject LazyAssemblyLoader AssemblyLoader
<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 List<Assembly>();
private async Task OnNavigateAsync(NavigationContext args)
{
try
{
if (args.Path == "robot")
{
var assemblies = await AssemblyLoader.LoadAssembliesAsync(
new[] { "GrantImaharaRobotControls.{FILE EXTENSION}" });
lazyLoadedAssemblies.AddRange(assemblies);
}
}
catch (Exception ex)
{
Logger.LogError("Error: {Message}", ex.Message);
}
}
}
Générez et exécutez l'application.
Si le composant Robot
de la RCL est demandé au niveau /robot
, l’assembly GrantImaharaRobotControls.{FILE EXTENSION}
est chargé et le composant Robot
est rendu. Vous pouvez inspecter le chargement de l’assembly dans l’onglet Réseau des outils pour développeurs du navigateur.
Note
Le chargement de types à partir d’un assembly chargé en mode différé est connu pour générer un problème. Pour plus d’informations, consultez Blazor WebAssembly lazy loading assemblies not working when using @ref attribute in the component (dotnet/aspnetcore #29342).
Commentaires sur ASP.NET Core
ASP.NET Core est un projet open source. Sélectionnez un lien pour fournir des commentaires :
Événement
Championnats du monde Power BI DataViz
14 févr., 16 h - 31 mars, 16 h
Avec 4 chances d’entrer, vous pourriez gagner un package de conférence et le rendre à la Live Grand Finale à Las Vegas
En savoir plusFormation
Module
Utiliser les pages, le routage et les dispositions pour améliorer la navigation Blazor - Training
Découvrez comment optimiser la navigation de votre application, utiliser des paramètres de l’URL et créer des dispositions réutilisables dans une application Web Blazor.