Fermer

décembre 17, 2024

Optimisation des performances dans Blazor WebAssembly

Optimisation des performances dans Blazor WebAssembly


Découvrez différentes façons d’améliorer les performances d’une application Blazor WebAssembly.

Le plus grand défi et la plus grande critique à laquelle Blazor WebAssembly est confronté sont ses performances.

Avant que l’application ne soit rendue sur le client, le bundle WebAssembly, comprenant un runtime .NET, doit être téléchargé avant le démarrage du rendu de la page.

Dans cet article, je discuterai de quelques options pour améliorer les performances d’une application Blazor WebAssembly. Nous commencerons par des recommandations générales et des bonnes pratiques pour le développement de Blazor avant de plonger en profondeur dans les optimisations de performances applicables uniquement aux applications Blazor WebAssembly.

Conseils pour un rendu optimisé des composants

Avant d’aborder des sujets plus avancés, commençons par voir comment améliorer les performances de rendu des composants Razor.

Contrôle du comportement de re-rendu

Si nous avons un sous-arbre de composants avec de nombreux sous-composants ou un (re)chargement de données coûteux, nous pouvons empêcher le composant parent de (re)rendre l’ensemble du sous-arbre.

Ce qui semble abstrait peut être mieux illustré à l’aide d’un exemple :

Disons que nous avons un tableau de bord affichant des informations sur différents domaines de l’application. Nous souhaitons maintenant exécuter une action gérée sur la page du tableau de bord, comme cliquer sur un bouton.

La page du tableau de bord exécutera le gestionnaire de clics et fournira un nouvel ensemble de valeurs de paramètres à tous les composants enfants, ce qui pourrait permettre à tous les sous-composants de restituer et de recharger leurs données.

Il existe deux approches que nous pouvons utiliser pour éviter de restituer un sous-arbre particulier dans un composant Razor :

  1. Implémentez des composants enfants avec des types primitifs et immuables, tels que int, bool, DateTime, string ou similaire. Ces types peuvent être évalués par le framework pour détecter tout changement. S’il n’y a aucun changement, le composant enfant (et ses enfants) ne seront pas restitués.
  2. Implémenter ou remplacer le ShouldRender méthode dans le composant enfant. Cette méthode de cycle de vie fournit une interface pour décider par programme si un composant (enfant) doit être restitué.
    Cette approche est particulièrement recommandée lors de l’implémentation d’un composant qui n’a jamais besoin d’être restitué après son rendu initial ou lors de l’utilisation de types de données complexes comme paramètres, tels que des classes personnalisées et des types d’enregistrement.

L’exemple de code suivant montre une implémentation typique de OnParametersSet et le ShouldRender méthodes de cycle de vie dans un composant Razor :

<h3>@Title - @Price.ToString("C")</h3>

@code {
    public string Title { get; set; } = "";
    public decimal Price { get; set; } = 0m;

    private bool _shouldRender = false;

    [Parameter]
    public CarInfo? Data { get; set; }

    protected override void OnParametersSet()
    {
        if( Data != null)
        {
            _shouldRender = Data.Price != Price;

            Title = Data.Name;
            Price = Data.Price;
        }
    }

    protected override bool ShouldRender()
    {
        return _shouldRender;
    }

    public record CarInfo(string Name, decimal Price);
}

Dans cet exemple, nous avons un composant restituant une voiture dans une application de concessionnaire automobile.

Nous avons un _shouldRender champ, que nous définissons sur true si nous devons restituer le composant. Le ShouldRender la mise en œuvre est assez simple et renvoie ceci _shouldRender champ, que nous plaçons à l’intérieur du OnParametersSet méthode.

Le OnParametersSet La méthode vérifie d’abord le paramètre pour un null valeur et définit la _shouldRender champ à true si le nouveau prix diffère du prix précédemment rendu.

En fonction de la logique de votre application, vous définissez les propriétés sur les nouvelles valeurs de paramètre si vous effectuez un nouveau rendu du composant.

Virtualisation des composants

La virtualisation des composants améliore les performances lors du rendu d’un longue liste d’élémentscomme une grille ou une table géante. L’objectif est de restituer uniquement les éléments visibles à l’écran, plus quelques éléments pré-rendus.

Lorsque l’utilisateur fait défiler la page, de nouveaux éléments sont affichés et les éléments qui ne sont plus à l’écran sont supprimés du DOM pour économiser de la mémoire et améliorer les performances de l’application.

L’exemple suivant montre une implémentation utilisant le module intégré Virtualize composant:

<Virtualize Items="Orders" Context="order">
    <div style="display:flex;">
        <div style="width: 400px;">@order.Id</div>
        <div>$ @order.Value</div>
    </div>
</Virtualize>

Dans cet exemple, nous rendons les éléments d’un Orders propriété de collection et utiliser le Context propriété pour rendre un élément spécifique disponible aux composants enfants.

Tout le rendu est pris en charge par le module intégré Virtualize composant. Cela améliore considérablement les performances des grandes listes, en particulier lorsque chaque élément a un arbre de rendu complexe et est assez simple à mettre en œuvre.

Vous pouvez en apprendre davantage sur Virtualisation des composants dans un article dédié dans le Les bases du Blazor série.

Optimiser les performances d’interopérabilité JavaScript

Lorsque vous utilisez l’interopérabilité JavaScript, il est important de comprendre qu’à chaque appel, il y a une certaine surcharge de communication.

Il est recommandé de limiter le nombre d’appels de .NET vers JavaScript et vice versa.

Il est préférable d’avoir un seul appel et de fournir un objet de données plus complexe pour envoyer toutes les informations requises en un seul appel plutôt que d’avoir plusieurs appels, chacun contenant des données limitées.

Compilation anticipée (AOT)

Alors que les optimisations de performances précédentes étaient également applicables à l’interactivité de Blazor Server, à commencer par compilation à l’avance (AOT)nous examinerons les optimisations exclusivement applicables aux applications Blazor WebAssembly.

Avec la compilation AOT, nous pouvons compiler une application Blazor en code WebAssembly natif, qui peut être directement exécuté par le navigateur.

Sans AOT, le client télécharge le bundle WebAssembly, y compris le runtime .NET, et exécute le code .NET à l’aide du compilateur juste à temps (JIT).

Les applications compilées par AOT prennent plus de temps à télécharger car la taille binaire est plus grande que celle d’une application compilée par JIT. Cependant, AOT offre de meilleures performances d’exécution.

Dans des scénarios contrôlés où vous déployez une application pour vos employés internes, l’utilisation d’applications de compilateur AOT peut être intéressante car il ne faut qu’une seule fois à l’employé pour télécharger l’application et bénéficier de meilleures performances à chaque fois qu’il utilise l’application.

L’implémentation d’AOT sort du cadre de cet article, lisez la documentation officielle pour plus d’informations sur implémentation de la compilation AOT dans les applications Blazor WebAssembly.

Servir des fichiers compressés

Une application Blazor WebAssembly ne nécessite pas ASP.NET Core sur le serveur. Au lieu de cela, nous pouvons déployer une application Blazor WebAssembly en tant qu’application Web statique sur n’importe quel serveur Web.

Assurez-vous que les fichiers sont servis en utilisant la compression Brotli (br) ou Gzip (gz).

Utilisez l’onglet Réseau dans les outils de développement de votre navigateur préféré et inspectez le Content-Encoding En-tête HTTP.

Si votre serveur Web ne sert pas les fichiers à l’aide de la compression, suivez les instructions sur votre serveur Web pour implémenter la compression afin de servir votre application Blazor WebAssembly.

Ne pas attacher le débogueur

L’attachement du débogueur prend beaucoup de temps. Si vous lancez sans cela, le démarrage devrait être sensiblement plus rapide.

Souvent, nous souhaitons tester une fonctionnalité ou travailler sur le style CSS de l’application ou implémenter un nouveau composant. Dans ces cas, nous n’avons pas besoin de débogueur.

L’exécution de l’application Blazor WebAssembly sans débogueur peut considérablement améliorer les performances de démarrage.

Conclusion

Bien que Blazor WebAssembly améliore ses performances à chaque nouvelle version de .NET, nous pouvons également l’améliorer en suivant les meilleures pratiques.

Nous voulons éviter un nouveau rendu inutile des composants Razor en contrôlant le comportement de rendu à l’aide de paramètres de composant primitifs ou en remplaçant le ShouldRender méthode du cycle de vie.

Le cas échéant, virtualisation des composants permet de restituer de grandes listes et des tableaux comportant de nombreuses lignes en rendant uniquement les lignes visibles à l’utilisateur. Cela améliore les performances de rendu et économise de la mémoire.

Lorsque vous utilisez l’interopérabilité JavaScript, tenez compte de la surcharge provoquée par chaque appel. Il faut éviter de l’appeler trop souvent. Au lieu de cela, nous devrions optimiser le code et fournir autant d’informations que possible avec un seul appel d’interopérabilité JavaScript.

La compilation anticipée (AOT) peut améliorer les performances de l’application et augmenter le bundle WebAssembly : c’est un compromis.

Lors de la configuration d’un serveur Web exécutant une application Blazor WebAssembly, nous devons nous assurer que nous utilisons la compression pour accélérer le téléchargement du bundle WebAssembly.

L’attachement du débogueur peut prendre un certain temps. Pensez à démarrer l’application sans attacher le débogueur lorsque vous n’en avez pas besoin.

Si vous souhaitez en savoir plus sur le développement de Blazor, vous pouvez regarder mon cours intensif Blazor gratuit sur YouTube. Et restez à l’écoute du blog Telerik pour en savoir plus Les bases du Blazor.




Source link