Partager via


Temps de démarrage d’une application

La quantité de temps nécessaire pour démarrer une application WPF peut varier considérablement. Cette rubrique décrit les différentes techniques permettant de réduire le temps de démarrage (perçu et réel) pour une application Windows Presentation Foundation (WPF).

Présentation de démarrage à froid et du démarrage à chaud

Le démarrage à froid se produit lorsque votre application démarre pour la première fois après un redémarrage du système, ou lorsque vous démarrez votre application, la fermez, puis la démarrez à nouveau après un certain temps. Lorsqu’une application démarre, si les pages requises (code, données statiques, registre, etc.) ne sont pas présentes dans la liste d’attente du Gestionnaire de mémoire Windows, des défauts de page se produisent. L’accès au disque est requis pour mettre les pages en mémoire.

Le démarrage à chaud se produit lorsque la plupart des pages pour les principaux composants du common language runtime (CLR) sont déjà chargés en mémoire, ce qui réduit le temps d’accès disque coûteux. C’est pourquoi une application managée démarre plus vite lorsqu’elle s’exécute une deuxième fois.

Implémentation d’un écran de démarrage

Dans les cas où il y a un délai notable et inévitable entre le démarrage d’une application et l’affichage de la première interface utilisateur, optimisez le temps de démarrage perçu à l’aide un écran de démarrage. Cette approche affiche une image presque immédiatement après que l’utilisateur démarre l’application. Lorsque l’application est prête à afficher sa première interface utilisateur, l’écran de démarrage disparaît en fondu. À partir du .NET Framework 3.5 SP1, vous pouvez utiliser la SplashScreen classe pour implémenter un écran de démarrage. Pour plus d’informations, consultez Ajouter un écran de démarrage dans une application WPF.

Vous pouvez également implémenter votre propre écran de démarrage à l’aide des graphiques Win32 natifs. Affichez votre implémentation avant l’appel de la Run méthode.

Analyse du code de démarrage

Déterminez la raison pour un démarrage à froid lent. Les E/S du disque peuvent être en cause, mais cela n’est pas toujours le cas. En général, vous devez réduire l’utilisation des ressources externes, comme le réseau, les services web ou le disque.

Avant de tester, vérifiez qu’il n’y pas d’autres applications ou services utilisant du code managé ou WPF.

Démarrez votre application WPF immédiatement après un redémarrage et déterminez la durée avant affichage. Si tous les lancements suivants de votre application (démarrage à chaud) sont beaucoup plus rapides, le problème du démarrage à froid est probablement causé par les E/S.

Si le problème de démarrage à froid de votre application n’est pas lié aux E/S, il est probable que votre application effectue une initialisation ou un calcul de longue durée, attende qu’un événement se termine ou nécessite beaucoup de compilation JIT au démarrage. Les sections suivantes décrivent certaines de ces situations plus en détail.

Optimisation du chargement des modules

Utilisez des outils tels que Process Explorer (Procexp.exe) et Tlist.exe pour déterminer les modules que votre application charge. La commande Tlist <pid> montre tous les modules chargés par un processus.

Par exemple, si vous n’êtes pas connecté à Internet et que vous voyez que System.Web.dll est chargé, il existe un module dans votre application qui fait référence à cet assembly. Vérifiez que la référence est nécessaire.

Si votre application comporte plusieurs modules, fusionnez-les en un seul module. Cette approche nécessite moins de surcharge de chargement d’assemblys CLR. Avoir moins d’assemblys signifie également que le CLR a moins d’états à maintenir.

Report des opérations d’initialisation

Envisagez de différer le code d’initialisation jusqu'au rendu de la fenêtre principale de l’application.

N’oubliez pas que l’initialisation peut être effectuée à l’intérieur d’un constructeur de classe, et que si le code d’initialisation référence d’autres classes, cela peut provoquer un effet de cascade dans lequel de nombreux constructeurs de classe sont exécutés.

Éviter la configuration d'application

Envisagez d’éviter la configuration de l’application. Par exemple, si une application a des exigences de configuration simples et des objectifs de temps de démarrage stricts, des entrées de registre ou un fichier INI simple peuvent être une alternative de démarrage plus rapide.

Utiliser le GAC

Si un assembly n’est pas installé dans le Global Assembly Cache (GAC), des retards sont causés par la vérification du hachage des assemblys avec nom fort et la validation des images Ngen si une image native de cet assembly est disponible sur l’ordinateur. La vérification des noms forts est ignorée pour tous les assemblys installés dans le GAC. Pour plus d'informations, consultez Gacutil.exe (Global Assembly Cache Tool).

Utiliser Ngen.exe

Envisagez d’utiliser Native Image Generator (Ngen.exe) sur votre application. L’utilisation de Ngen.exe signifie que vous remplacez une partie de la consommation d’UC par plus d’accès au disque, car l’image native générée par Ngen.exe est susceptible d’être plus grande que l’image MSIL.

Pour améliorer le temps de démarrage à chaud, vous devez toujours utiliser Ngen.exe sur votre application, car cela vous fait économiser le coût de la compilation JIT du code d’application par l’UC.

Dans certains scénarios de démarrage à froid, Ngen.exe peut également s’avérer utile. En effet, le compilateur JIT (mscorjit.dll) ne devra pas être chargé dans ce cas.

La présence à la fois de modules Ngen et JIT peut avoir le pire effet. En effet, mscorjit.dll doit être chargé, et lorsque le compilateur JIT travaille sur votre code, l’accès à de nombreuses pages dans les images Ngen est nécessaire lorsque le compilateur JIT lit les métadonnées des assemblys.

ClickOnce et Ngen

La façon dont vous prévoyez de déployer votre application peut également faire une différence dans le temps de chargement. Le déploiement d’applications ClickOnce ne prend pas en charge Ngen. Si vous décidez d’utiliser Ngen.exe pour votre application, vous devez utiliser un autre mécanisme de déploiement, comme Windows Installer.

Pour plus d’informations, consultez Ngen.exe (Native Image Generator).

Relocalisation et collisions d’adresses DLL

Si vous utilisez Ngen.exe, sachez que la relocalisation peut se produire lorsque des images natives sont chargées en mémoire. Si une DLL n’est pas chargée à son adresse de base préférée car cette plage d’adresses est déjà allouée, le chargeur Windows la chargera à une autre adresse, ce qui peut prendre beaucoup de temps.

Vous pouvez utiliser l’outil Virtual Address Dump (Vadump.exe) pour vérifier s’il existe des modules dans lesquels toutes les pages sont privées. Si c’est le cas, le module a peut-être été relocalisé à une adresse différente. Par conséquent, ses pages ne peuvent pas être partagées.

Pour plus d’informations sur la définition de l’adresse de base, consultez Ngen.exe (Native Image Generator).

Optimiser Authenticode

La vérification Authenticode ajoute au temps de démarrage. Les assemblys signés par Authenticode doivent être vérifiés avec l’autorité de certification (CA). Cette vérification peut prendre du temps, car elle peut requérir la connexion au réseau à plusieurs reprises pour télécharger les listes de révocation de certificats actuelles. Cela garantit également qu’il existe une chaîne complète de certificats valides sur le chemin d’accès à une racine approuvée. Cela peut se traduire par plusieurs secondes de délai lors du chargement de l’assembly.

Envisagez d’installer le certificat d’autorité de certification sur l’ordinateur client, ou évitez d’utiliser Authenticode lorsque c’est possible. Si vous savez que votre application ne nécessite pas de preuve de l’éditeur, vous n’avez pas à payer le coût de la vérification de la signature.

À compter de .NET Framework 3.5, il existe une option de configuration qui permet à la vérification Authenticode d’être ignorée. Pour ce faire, ajoutez le paramètre suivant au fichier app.exe.config :

<configuration>  
    <runtime>  
        <generatePublisherEvidence enabled="false"/>
    </runtime>  
</configuration>  

Pour plus d’informations, consultez <generatePublisherEvidence> , élément.

Comparaison des performances sur Windows Vista

Le gestionnaire de mémoire dans Windows Vista possède une technologie appelée SuperFetch. SuperFetch analyse les modèles d’utilisation de la mémoire au fil du temps pour déterminer le contenu de mémoire optimal pour un utilisateur spécifique. Il fonctionne en continu pour conserver ce contenu à tout moment.

Cette approche diffère de la technique de prérécupération utilisée dans Windows XP, qui précharge les données en mémoire sans analyser les modèles d’utilisation. Au fil du temps, si l’utilisateur utilise fréquemment votre application WPF sur Windows Vista, le temps de démarrage à froid de votre application peut s’améliorer.

Utiliser efficacement les AppDomains

Si possible, chargez les assemblys dans une zone de code indépendante du domaine pour vous assurer que l’image native, s’il en existe une, est utilisée dans tous les AppDomains créés dans l’application.

Pour des performances optimales, appliquez une communication interdomaine efficace en réduisant les appels interdomaines. Si possible, utilisez des appels sans arguments ou avec des arguments de type primitif.

Utilisation de l’attribut NeutralResourcesLanguage

Utilisez la NeutralResourcesLanguageAttribute propriété pour spécifier la culture neutre pour le ResourceManager. Cette approche évite les échecs de recherche d’assembly.

Utilisation de la classe BinaryFormatter pour la sérialisation

Si vous devez utiliser la sérialisation, utilisez la BinaryFormatter classe au lieu de la XmlSerializer classe. La BinaryFormatter classe est implémentée dans la bibliothèque de classes de base (BCL) dans l’assembly mscorlib.dll. Il XmlSerializer est implémenté dans l’assembly System.Xml.dll, qui peut être une DLL supplémentaire à charger.

Si vous devez utiliser la XmlSerializer classe, vous pouvez obtenir de meilleures performances si vous prégénéez l’assembly de sérialisation.

Configuration de ClickOnce pour vérifier les mises à jour après le démarrage

Si votre application utilise ClickOnce, évitez l’accès réseau au démarrage en configurant ClickOnce pour case activée le site de déploiement pour les mises à jour après le démarrage de l’application.

Si vous utilisez le modèle d’application de navigateur XAML (XBAP), gardez à l’esprit que ClickOnce case activée le site de déploiement pour les mises à jour, même si le XBAP se trouve déjà dans le cache ClickOnce. Pour plus d'informations, consultez ClickOnce Security and Deployment.

Avertissement

Les XBAPs nécessitent que les navigateurs hérités fonctionnent, tels qu’Internet Explorer et Firefox. Ces versions de navigateur plus anciennes ne sont généralement pas prises en charge sur Windows 10 et Windows 11. Les navigateurs modernes ne prennent plus en charge la technologie requise pour les applications XBAP en raison des risques de sécurité. Les plug-ins qui activent les XBAPs ne sont plus pris en charge.

Configuration du service PresentationFontCache pour qu’il démarre automatiquement

La première application WPF qui s’exécute après un redémarrage est le service PresentationFontCache. Le service met en cache les polices système améliore l’accès aux polices et augmente les performances globales. Il existe une surcharge du démarrage du service, et dans certains environnements contrôlés, envisagez de configurer le service pour démarrer automatiquement lors du redémarrage du système.

Définition des données de liaison par programmation

Au lieu d’utiliser XAML pour définir de DataContext manière déclarative pour la fenêtre principale, envisagez de la définir par programmation dans la OnActivated méthode.

Voir aussi