I noticed that WPF application startup is sometimes pretty slow. Does anybody know if the the cause is the elements initialization or DLLs loading or something else?
我注意到WPF应用程序启动有时候很慢。有没有人知道原因是元素初始化还是DLL加载或其他什么?
5 个解决方案
#1
16
The text below was extracted from this MSDN article on Improving WPF applications startup time (Edit: now merged into WPF Application Startup Time)
下面的文本摘自这篇关于改进WPF应用程序启动时间的MSDN文章(编辑:现在合并到WPF应用程序启动时间)
Application Startup Time
The amount of time that is required for a WPF application to start can vary greatly. This topic describes various techniques for reducing the perceived and actual startup time for a Windows Presentation Foundation (WPF) application.
WPF应用程序启动所需的时间差异很大。本主题描述了用于减少Windows Presentation Foundation(WPF)应用程序的感知和实际启动时间的各种技术。
Understanding Cold Startup and WarmStartup
了解Cold Startup和WarmStartup
Cold startup occurs when your application starts for the first time after a system reboot, or when you start your application, close it, and then start it again after a long period of time. When an application starts, if the required pages (code, static data, registry, etc) are not present in the Windows memory manager's standby list, page faults occur. Disk access is required to bring the pages into memory.
当您的应用程序在系统重新启动后第一次启动时,或启动应用程序,关闭它,然后在很长一段时间后再次启动时,就会发生冷启动。当应用程序启动时,如果Windows内存管理器的备用列表中不存在所需的页面(代码,静态数据,注册表等),则会发生页面错误。需要磁盘访问才能将页面带入内存。
Warm startup occurs when most of the pages for the main common language runtime (CLR) components are already loaded in memory, which saves expensive disk access time. That is why a managed application starts faster when it runs a second time.
当主公共语言运行时(CLR)组件的大多数页面已经加载到内存中时,会发生热启动,从而节省了昂贵的磁盘访问时间。这就是托管应用程序第二次运行时启动速度更快的原因。
Implement a Splash Screen
实现启动画面
In cases where there is a significant, unavoidable delay between starting an application and displaying the first UI, optimize the perceived startup time by using a splash screen. This approach displays an image almost immediately after the user starts the application. When the application is ready to display its first UI, the splash screen fades. Starting in the .NET Framework 3.5 SP1, you can use the SplashScreen class to implement a splash screen. For more information, see How to: Add a Splash Screen to a WPF Application.
如果在启动应用程序和显示第一个UI之间存在显着的,不可避免的延迟,请使用启动屏幕优化感知的启动时间。此方法几乎在用户启动应用程序后立即显示图像。当应用程序准备好显示其第一个UI时,启动屏幕会消失。从.NET Framework 3.5 SP1开始,您可以使用SplashScreen类来实现启动屏幕。有关更多信息,请参见如何:向WPF应用程序添加启动画面。
You can also implement your own splash screen by using native Win32 graphics. Display your implementation before the Run method is called.
您还可以使用本机Win32图形实现自己的启动屏幕。在调用Run方法之前显示您的实现。
Analyze the Startup Code
分析启动代码
Determine the reason for a slow cold startup. Disk I/O may be responsible, but this is not always the case. In general, you should minimize the use of external resources, such as network, Web services, or disk.
确定冷启动缓慢的原因。磁盘I / O可能是负责任的,但情况并非总是如此。通常,应尽量减少外部资源的使用,例如网络,Web服务或磁盘。
Before you test, verify that no other running applications or services use managed code or WPF code.
在测试之前,请验证没有其他正在运行的应用程序或服务使用托管代码或WPF代码。
Start your WPF application immediately after a reboot, and determine how long it takes to display. If all subsequent launches of your application (warm startup) are much faster, your cold startup issue is most likely caused by I/O.
重新启动后立即启动WPF应用程序,并确定显示所需的时间。如果应用程序的所有后续启动(热启动)都要快得多,那么您的冷启动问题很可能是由I / O引起的。
If your application's cold startup issue is not related to I/O, it is likely that your application performs some lengthy initialization or computation, waits for some event to complete, or requires a lot of JIT compilation at startup. The following sections describe some of these situations in more detail.
如果您的应用程序的冷启动问题与I / O无关,则可能是您的应用程序执行了一些冗长的初始化或计算,等待某些事件完成,或者在启动时需要大量的JIT编译。以下部分更详细地描述了其中一些情况。
Optimize Module Loading
优化模块加载
Use tools such as Process Explorer (Procexp.exe) and Tlist.exe to determine which modules your application loads. The command Tlist <pid> shows all the modules that are loaded by a process.
使用Process Explorer(Procexp.exe)和Tlist.exe等工具确定应用程序加载的模块。命令Tlist
For example, if you are not connecting to the Web and you see that System.Web.dll is loaded, then there is a module in your application that references this assembly. Check to make sure that the reference is necessary.
例如,如果您没有连接到Web并且看到加载了System.Web.dll,则应用程序中有一个模块引用此程序集。检查以确保必须参考。
If your application has multiple modules, merge them into a single module. This approach requires less CLR assembly-loading overhead. Fewer assemblies also mean that the CLR maintains less state.
如果您的应用程序有多个模块,请将它们合并到一个模块中。这种方法需要较少的CLR组装负载开销。较少的组件也意味着CLR保持较少的状态。
Defer Initialization Operations
推迟初始化操作
Consider postponing initialization code until after the main application window is rendered.
考虑推迟初始化代码,直到呈现主应用程序窗口。
Be aware that initialization may be performed inside a class constructor, and if the initialization code references other classes, it can cause a cascading effect in which many class constructors are executed.
请注意,可以在类构造函数中执行初始化,如果初始化代码引用其他类,则可能会导致执行许多类构造函数的级联效果。
Avoid Application Configuration
避免应用配置
Consider avoiding application configuration. For example, if an application has simple configuration requirements and has strict startup time goals, registry entries or a simple INI file may be a faster startup alternative.
考虑避免应用配置。例如,如果应用程序具有简单的配置要求并且具有严格的启动时间目标,则注册表项或简单的INI文件可能是更快的启动替代方案。
Utilize the GAC
利用GAC
If an assembly is not installed in the Global Assembly Cache (GAC), there are delays caused by hash verification of strong-named assemblies and by Ngen image validation if a native image for that assembly is available on the computer. Strong-name verification is skipped for all assemblies installed in the GAC. For more information, see Gacutil.exe (Global Assembly Cache Tool).
如果未在全局程序集缓存(GAC)中安装程序集,则如果计算机上可用该程序集的本机映像,则由强名称程序集的哈希验证和Ngen映像验证导致延迟。对于GAC中安装的所有程序集,将跳过强名称验证。有关更多信息,请参阅Gacutil.exe(全局程序集缓存工具)。
Use Ngen.exe
使用Ngen.exe
Consider using the Native Image Generator (Ngen.exe) on your application. Using Ngen.exe means trading CPU consumption for more disk access because the native image generated by Ngen.exe is likely to be larger than the MSIL image.
考虑在您的应用程序上使用本机映像生成器(Ngen.exe)。使用Ngen.exe意味着交换CPU消耗以获得更多磁盘访问权限,因为Ngen.exe生成的本机映像可能比MSIL映像更大。
To improve the warm startup time, you should always use Ngen.exe on your application, because this avoids the CPU cost of JIT compilation of the application code.
要改善热启动时间,应始终在应用程序上使用Ngen.exe,因为这样可以避免应用程序代码的JIT编译的CPU成本。
In some cold startup scenarios, using Ngen.exe can also be helpful. This is because the JIT compiler (mscorjit.dll) does not have to be loaded.
在某些冷启动方案中,使用Ngen.exe也很有帮助。这是因为不必加载JIT编译器(mscorjit.dll)。
Having both Ngen and JIT modules can have the worst effect. This is because mscorjit.dll must be loaded, and when the JIT compiler works on your code, many pages in the Ngen images must be accessed when the JIT compiler reads the assemblies' metadata.
同时使用Ngen和JIT模块会产生最坏的影响。这是因为必须加载mscorjit.dll,并且当JIT编译器处理您的代码时,必须在JIT编译器读取程序集的元数据时访问Ngen映像中的许多页面。
Ngen and ClickOnce
Ngen和ClickOnce
The way you plan to deploy your application can also make a difference in load time. ClickOnce application deployment does not support Ngen. If you decide to use Ngen.exe for your application, you will have to use another deployment mechanism, such as Windows Installer.
您计划部署应用程序的方式也会对加载时间产生影响。 ClickOnce应用程序部署不支持Ngen。如果您决定将Ngen.exe用于您的应用程序,则必须使用其他部署机制,例如Windows Installer。
For more information, see Ngen.exe (Native Image Generator).
有关更多信息,请参阅Ngen.exe(本机映像生成器)。
Rebasing and DLL Address Collisions
重新定位和DLL地址冲突
If you use Ngen.exe, be aware that rebasing can occur when the native images are loaded in memory. If a DLL is not loaded at its preferred base address because that address range is already allocated, the Windows loader will load it at another address, which can be a time-consuming operation.
如果您使用Ngen.exe,请注意在本机映像加载到内存时可能会发生变基。如果DLL未在其首选基址加载,因为已经分配了该地址范围,则Windows加载程序会将其加载到另一个地址,这可能是一个非常耗时的操作。
You can use the Virtual Address Dump (Vadump.exe) tool to check if there are modules in which all the pages are private. If this is the case, the module may have been rebased to a different address. Therefore, its pages cannot be shared.
您可以使用虚拟地址转储(Vadump.exe)工具检查是否存在所有页面都是私有的模块。如果是这种情况,则模块可能已重新定位到不同的地址。因此,其页面无法共享。
For more information about how to set the base address, see Ngen.exe (Native Image Generator).
有关如何设置基址的详细信息,请参阅Ngen.exe(本机映像生成器)。
Optimize Authenticode
优化Authenticode
Authenticode verification adds to the startup time. Authenticode-signed assemblies have to be verified with the certification authority (CA). This verification can be time consuming, because it can require connecting to the network several times to download current certificate revocation lists. It also makes sure that there is a full chain of valid certificates on the path to a trusted root. This can translate to several seconds of delay while the assembly is being loaded.
Authenticode验证会增加启动时间。必须使用证书颁发机构(CA)验证Authenticode签名的程序集。此验证可能非常耗时,因为它可能需要多次连接到网络才能下载当前的证书吊销列表。它还确保在到受信任根的路径上有完整的有效证书链。加载程序集时,这可能会转换为几秒钟的延迟。
Consider installing the CA certificate on the client computer, or avoid using Authenticode when it is possible. If you know that your application does not need the publisher evidence, you do not have to pay the cost of signature verification.
请考虑在客户端计算机上安装CA证书,或者尽可能避免使用Authenticode。如果您知道您的申请不需要出版商证明,则无需支付签名验证费用。
Starting in .NET Framework 3.5, there is a configuration option that allows the Authenticode verification to be bypassed. To do this, add the following setting to the app.exe.config file:
从.NET Framework 3.5开始,有一个配置选项允许绕过Authenticode验证。为此,请将以下设置添加到app.exe.config文件中:
<configuration>
<runtime>
<generatePublisherEvidence enabled="false"/>
</runtime>
</configuration>
Compare Performance on Windows Vista
在Windows Vista上比较性能
The memory manager in Windows Vista has a technology called SuperFetch. SuperFetch analyzes memory usage patterns over time to determine the optimal memory content for a specific user. It works continuously to maintain that content at all times.
Windows Vista中的内存管理器有一项名为SuperFetch的技术。 SuperFetch随时间分析内存使用模式,以确定特定用户的最佳内存内容。它始终持续工作以维护该内容。
This approach differs from the pre-fetch technique used in Windows XP, which preloads data into memory without analyzing usage patterns. Over time, if the user uses your WPF application frequently on Windows Vista, the cold startup time of your application may improve.
这种方法不同于Windows XP中使用的预取技术,它在不分析使用模式的情况下将数据预加载到内存中。随着时间的推移,如果用户经常在Windows Vista上使用WPF应用程序,则应用程序的冷启动时间可能会有所改善。
Use AppDomains Efficiently
有效地使用AppDomains
If possible, load assemblies into a domain-neutral code area to make sure that the native image, if one exists, is used in all AppDomains created in the application.
如果可能,将程序集加载到域中性代码区域,以确保在应用程序中创建的所有AppDomain中使用本机映像(如果存在)。
For the best performance, enforce efficient cross-domain communication by reducing cross-domain calls. When possible, use calls without arguments or with primitive type arguments.
为获得最佳性能,请通过减少跨域调用来实施高效的跨域通信。如果可能,请使用不带参数的调用或使用基本类型参数。
Use the NeutralResourcesLanguage Attribute
使用NeutralResourcesLanguage属性
Use the NeutralResourcesLanguageAttribute to specify the neutral culture for the ResourceManager. This approach avoids unsuccessful assembly lookups.
使用NeutralResourcesLanguageAttribute为ResourceManager指定中性文化。这种方法避免了不成功的程序集查找。
Use the BinaryFormatter Class for Serialization
使用BinaryFormatter类进行序列化
If you must use serialization, use the BinaryFormatter class instead of the XmlSerializer class. The BinaryFormatter class is implemented in the Base Class Library (BCL) in the mscorlib.dll assembly. The XmlSerializer is implemented in the System.Xml.dll assembly, which might be an additional DLL to load.
如果必须使用序列化,请使用BinaryFormatter类而不是XmlSerializer类。 BinaryFormatter类在mscorlib.dll程序集中的基类库(BCL)中实现。 XmlSerializer在System.Xml.dll程序集中实现,该程序集可能是要加载的其他DLL。
If you must use the XmlSerializer class, you can achieve better performance if you pre-generate the serialization assembly.
如果必须使用XmlSerializer类,则可以在预生成序列化程序集时获得更好的性能。
Configure ClickOnce to Check for Updates After Startup
启动后配置ClickOnce以检查更新
If your application uses ClickOnce, avoid network access on startup by configuring ClickOnce to check the deployment site for updates after the application starts.
如果您的应用程序使用ClickOnce,请通过配置ClickOnce以在应用程序启动后检查部署站点是否有更新来避免启动时的网络访问。
If you use the XAML browser application (XBAP) model, keep in mind that ClickOnce checks the deployment site for updates even if the XBAP is already in the ClickOnce cache. For more information, see ClickOnce Security and Deployment.
如果您使用XAML浏览器应用程序(XBAP)模型,请记住,即使XBAP已在ClickOnce缓存中,ClickOnce也会检查部署站点是否有更新。有关更多信息,请参阅ClickOnce安全性和部署。
Configure the PresentationFontCache Service to Start Automatically
将PresentationFontCache服务配置为自动启动
The first WPF application to run after a reboot is the PresentationFontCache service. The service caches the system fonts, improves font access, and improves overall performance. There is an overhead in starting the service, and in some controlled environments, consider configuring the service to start automatically when the system reboots.
重启后运行的第一个WPF应用程序是PresentationFontCache服务。该服务缓存系统字体,改进字体访问并提高整体性能。启动服务会产生开销,在某些受控环境中,请考虑将服务配置为在系统重新启动时自动启动。
Set Data Binding Programmatically
以编程方式设置数据绑定
Instead of using XAML to set the DataContext declaratively for the main window, consider setting it programmatically in the OnActivated method.
而不是使用XAML以声明方式为主窗口设置DataContext,请考虑在OnActivated方法中以编程方式设置它。
#2
2
The startup time of a WPF Application can be much faster if you use Framework 3.51 and not 3.5 or 3.0. The 3.51 is really an improvement.
如果使用Framework 3.51而不是3.5或3.0,WPF应用程序的启动时间会快得多。 3.51真的是一个改进。
#3
0
What helped me the most from the excellent article that Stuart links to was the XmlSerializer trick. That really shaved up quite a few seconds. Furthermore don't underestimate defragmenting your HD :-)
从Stuart链接的优秀文章中获得最大帮助的是XmlSerializer技巧。真的刮了几秒钟。此外,不要低估你的高清碎片整理:-)
#4
0
The most useful advice on fixing WPF startup performance I've ever seen was given in this other question: run "ngen update" in every framework folder.
关于修复我见过的WPF启动性能的最有用的建议是在另一个问题中给出的:在每个框架文件夹中运行“ngen update”。
It seems that Microsoft can't keep their ngen cache up-to-date, which results in your application pretty much recompiling half the .NET framework every single startup.
似乎微软无法使他们的ngen缓存保持最新状态,这导致您的应用程序在每次启动时都会重新编译.NET框架的一半。
Hard to believe, but seems to be true.
很难相信,但似乎是真的。
#5
0
This is an old thread, but I've ended up here several times while trying to fix a startup performance issue with WPF apps on my Win10 system, so I thought I'd state an answer which may help others - an answer that takes a horrible 5 second startup time for all WPF apps on this system down to just a few milliseconds. Remove the nVidia "3d Vision" driver. I have a GeForce GTX 650 card, and the "3d Vision" driver doesn't seem to offer anything useful, so removing it is no problem for me. The VisualStudio2015 performance analysis tool finally helped show that almost all the 5 second startup time was spent IDLE after a call through nvapi64.dll - the nVidia driver. Wow.
这是一个老线程,但我在Win10系统上试图用WPF应用程序修复启动性能问题时已经好几次了,所以我想我会说出一个可以帮助其他人的答案 - 这个答案需要一个这个系统上所有WPF应用的可怕5秒启动时间只有几毫秒。删除nVidia“3d Vision”驱动程序。我有一块GeForce GTX 650卡,“3d Vision”驱动程序似乎没有提供任何有用的东西,所以删除它对我来说没问题。 VisualStudio2015性能分析工具最终帮助显示,在通过nvapi64.dll(nVidia驱动程序)调用后,几乎所有5秒的启动时间都花费在IDLE上。哇。
#1
16
The text below was extracted from this MSDN article on Improving WPF applications startup time (Edit: now merged into WPF Application Startup Time)
下面的文本摘自这篇关于改进WPF应用程序启动时间的MSDN文章(编辑:现在合并到WPF应用程序启动时间)
Application Startup Time
The amount of time that is required for a WPF application to start can vary greatly. This topic describes various techniques for reducing the perceived and actual startup time for a Windows Presentation Foundation (WPF) application.
WPF应用程序启动所需的时间差异很大。本主题描述了用于减少Windows Presentation Foundation(WPF)应用程序的感知和实际启动时间的各种技术。
Understanding Cold Startup and WarmStartup
了解Cold Startup和WarmStartup
Cold startup occurs when your application starts for the first time after a system reboot, or when you start your application, close it, and then start it again after a long period of time. When an application starts, if the required pages (code, static data, registry, etc) are not present in the Windows memory manager's standby list, page faults occur. Disk access is required to bring the pages into memory.
当您的应用程序在系统重新启动后第一次启动时,或启动应用程序,关闭它,然后在很长一段时间后再次启动时,就会发生冷启动。当应用程序启动时,如果Windows内存管理器的备用列表中不存在所需的页面(代码,静态数据,注册表等),则会发生页面错误。需要磁盘访问才能将页面带入内存。
Warm startup occurs when most of the pages for the main common language runtime (CLR) components are already loaded in memory, which saves expensive disk access time. That is why a managed application starts faster when it runs a second time.
当主公共语言运行时(CLR)组件的大多数页面已经加载到内存中时,会发生热启动,从而节省了昂贵的磁盘访问时间。这就是托管应用程序第二次运行时启动速度更快的原因。
Implement a Splash Screen
实现启动画面
In cases where there is a significant, unavoidable delay between starting an application and displaying the first UI, optimize the perceived startup time by using a splash screen. This approach displays an image almost immediately after the user starts the application. When the application is ready to display its first UI, the splash screen fades. Starting in the .NET Framework 3.5 SP1, you can use the SplashScreen class to implement a splash screen. For more information, see How to: Add a Splash Screen to a WPF Application.
如果在启动应用程序和显示第一个UI之间存在显着的,不可避免的延迟,请使用启动屏幕优化感知的启动时间。此方法几乎在用户启动应用程序后立即显示图像。当应用程序准备好显示其第一个UI时,启动屏幕会消失。从.NET Framework 3.5 SP1开始,您可以使用SplashScreen类来实现启动屏幕。有关更多信息,请参见如何:向WPF应用程序添加启动画面。
You can also implement your own splash screen by using native Win32 graphics. Display your implementation before the Run method is called.
您还可以使用本机Win32图形实现自己的启动屏幕。在调用Run方法之前显示您的实现。
Analyze the Startup Code
分析启动代码
Determine the reason for a slow cold startup. Disk I/O may be responsible, but this is not always the case. In general, you should minimize the use of external resources, such as network, Web services, or disk.
确定冷启动缓慢的原因。磁盘I / O可能是负责任的,但情况并非总是如此。通常,应尽量减少外部资源的使用,例如网络,Web服务或磁盘。
Before you test, verify that no other running applications or services use managed code or WPF code.
在测试之前,请验证没有其他正在运行的应用程序或服务使用托管代码或WPF代码。
Start your WPF application immediately after a reboot, and determine how long it takes to display. If all subsequent launches of your application (warm startup) are much faster, your cold startup issue is most likely caused by I/O.
重新启动后立即启动WPF应用程序,并确定显示所需的时间。如果应用程序的所有后续启动(热启动)都要快得多,那么您的冷启动问题很可能是由I / O引起的。
If your application's cold startup issue is not related to I/O, it is likely that your application performs some lengthy initialization or computation, waits for some event to complete, or requires a lot of JIT compilation at startup. The following sections describe some of these situations in more detail.
如果您的应用程序的冷启动问题与I / O无关,则可能是您的应用程序执行了一些冗长的初始化或计算,等待某些事件完成,或者在启动时需要大量的JIT编译。以下部分更详细地描述了其中一些情况。
Optimize Module Loading
优化模块加载
Use tools such as Process Explorer (Procexp.exe) and Tlist.exe to determine which modules your application loads. The command Tlist <pid> shows all the modules that are loaded by a process.
使用Process Explorer(Procexp.exe)和Tlist.exe等工具确定应用程序加载的模块。命令Tlist
For example, if you are not connecting to the Web and you see that System.Web.dll is loaded, then there is a module in your application that references this assembly. Check to make sure that the reference is necessary.
例如,如果您没有连接到Web并且看到加载了System.Web.dll,则应用程序中有一个模块引用此程序集。检查以确保必须参考。
If your application has multiple modules, merge them into a single module. This approach requires less CLR assembly-loading overhead. Fewer assemblies also mean that the CLR maintains less state.
如果您的应用程序有多个模块,请将它们合并到一个模块中。这种方法需要较少的CLR组装负载开销。较少的组件也意味着CLR保持较少的状态。
Defer Initialization Operations
推迟初始化操作
Consider postponing initialization code until after the main application window is rendered.
考虑推迟初始化代码,直到呈现主应用程序窗口。
Be aware that initialization may be performed inside a class constructor, and if the initialization code references other classes, it can cause a cascading effect in which many class constructors are executed.
请注意,可以在类构造函数中执行初始化,如果初始化代码引用其他类,则可能会导致执行许多类构造函数的级联效果。
Avoid Application Configuration
避免应用配置
Consider avoiding application configuration. For example, if an application has simple configuration requirements and has strict startup time goals, registry entries or a simple INI file may be a faster startup alternative.
考虑避免应用配置。例如,如果应用程序具有简单的配置要求并且具有严格的启动时间目标,则注册表项或简单的INI文件可能是更快的启动替代方案。
Utilize the GAC
利用GAC
If an assembly is not installed in the Global Assembly Cache (GAC), there are delays caused by hash verification of strong-named assemblies and by Ngen image validation if a native image for that assembly is available on the computer. Strong-name verification is skipped for all assemblies installed in the GAC. For more information, see Gacutil.exe (Global Assembly Cache Tool).
如果未在全局程序集缓存(GAC)中安装程序集,则如果计算机上可用该程序集的本机映像,则由强名称程序集的哈希验证和Ngen映像验证导致延迟。对于GAC中安装的所有程序集,将跳过强名称验证。有关更多信息,请参阅Gacutil.exe(全局程序集缓存工具)。
Use Ngen.exe
使用Ngen.exe
Consider using the Native Image Generator (Ngen.exe) on your application. Using Ngen.exe means trading CPU consumption for more disk access because the native image generated by Ngen.exe is likely to be larger than the MSIL image.
考虑在您的应用程序上使用本机映像生成器(Ngen.exe)。使用Ngen.exe意味着交换CPU消耗以获得更多磁盘访问权限,因为Ngen.exe生成的本机映像可能比MSIL映像更大。
To improve the warm startup time, you should always use Ngen.exe on your application, because this avoids the CPU cost of JIT compilation of the application code.
要改善热启动时间,应始终在应用程序上使用Ngen.exe,因为这样可以避免应用程序代码的JIT编译的CPU成本。
In some cold startup scenarios, using Ngen.exe can also be helpful. This is because the JIT compiler (mscorjit.dll) does not have to be loaded.
在某些冷启动方案中,使用Ngen.exe也很有帮助。这是因为不必加载JIT编译器(mscorjit.dll)。
Having both Ngen and JIT modules can have the worst effect. This is because mscorjit.dll must be loaded, and when the JIT compiler works on your code, many pages in the Ngen images must be accessed when the JIT compiler reads the assemblies' metadata.
同时使用Ngen和JIT模块会产生最坏的影响。这是因为必须加载mscorjit.dll,并且当JIT编译器处理您的代码时,必须在JIT编译器读取程序集的元数据时访问Ngen映像中的许多页面。
Ngen and ClickOnce
Ngen和ClickOnce
The way you plan to deploy your application can also make a difference in load time. ClickOnce application deployment does not support Ngen. If you decide to use Ngen.exe for your application, you will have to use another deployment mechanism, such as Windows Installer.
您计划部署应用程序的方式也会对加载时间产生影响。 ClickOnce应用程序部署不支持Ngen。如果您决定将Ngen.exe用于您的应用程序,则必须使用其他部署机制,例如Windows Installer。
For more information, see Ngen.exe (Native Image Generator).
有关更多信息,请参阅Ngen.exe(本机映像生成器)。
Rebasing and DLL Address Collisions
重新定位和DLL地址冲突
If you use Ngen.exe, be aware that rebasing can occur when the native images are loaded in memory. If a DLL is not loaded at its preferred base address because that address range is already allocated, the Windows loader will load it at another address, which can be a time-consuming operation.
如果您使用Ngen.exe,请注意在本机映像加载到内存时可能会发生变基。如果DLL未在其首选基址加载,因为已经分配了该地址范围,则Windows加载程序会将其加载到另一个地址,这可能是一个非常耗时的操作。
You can use the Virtual Address Dump (Vadump.exe) tool to check if there are modules in which all the pages are private. If this is the case, the module may have been rebased to a different address. Therefore, its pages cannot be shared.
您可以使用虚拟地址转储(Vadump.exe)工具检查是否存在所有页面都是私有的模块。如果是这种情况,则模块可能已重新定位到不同的地址。因此,其页面无法共享。
For more information about how to set the base address, see Ngen.exe (Native Image Generator).
有关如何设置基址的详细信息,请参阅Ngen.exe(本机映像生成器)。
Optimize Authenticode
优化Authenticode
Authenticode verification adds to the startup time. Authenticode-signed assemblies have to be verified with the certification authority (CA). This verification can be time consuming, because it can require connecting to the network several times to download current certificate revocation lists. It also makes sure that there is a full chain of valid certificates on the path to a trusted root. This can translate to several seconds of delay while the assembly is being loaded.
Authenticode验证会增加启动时间。必须使用证书颁发机构(CA)验证Authenticode签名的程序集。此验证可能非常耗时,因为它可能需要多次连接到网络才能下载当前的证书吊销列表。它还确保在到受信任根的路径上有完整的有效证书链。加载程序集时,这可能会转换为几秒钟的延迟。
Consider installing the CA certificate on the client computer, or avoid using Authenticode when it is possible. If you know that your application does not need the publisher evidence, you do not have to pay the cost of signature verification.
请考虑在客户端计算机上安装CA证书,或者尽可能避免使用Authenticode。如果您知道您的申请不需要出版商证明,则无需支付签名验证费用。
Starting in .NET Framework 3.5, there is a configuration option that allows the Authenticode verification to be bypassed. To do this, add the following setting to the app.exe.config file:
从.NET Framework 3.5开始,有一个配置选项允许绕过Authenticode验证。为此,请将以下设置添加到app.exe.config文件中:
<configuration>
<runtime>
<generatePublisherEvidence enabled="false"/>
</runtime>
</configuration>
Compare Performance on Windows Vista
在Windows Vista上比较性能
The memory manager in Windows Vista has a technology called SuperFetch. SuperFetch analyzes memory usage patterns over time to determine the optimal memory content for a specific user. It works continuously to maintain that content at all times.
Windows Vista中的内存管理器有一项名为SuperFetch的技术。 SuperFetch随时间分析内存使用模式,以确定特定用户的最佳内存内容。它始终持续工作以维护该内容。
This approach differs from the pre-fetch technique used in Windows XP, which preloads data into memory without analyzing usage patterns. Over time, if the user uses your WPF application frequently on Windows Vista, the cold startup time of your application may improve.
这种方法不同于Windows XP中使用的预取技术,它在不分析使用模式的情况下将数据预加载到内存中。随着时间的推移,如果用户经常在Windows Vista上使用WPF应用程序,则应用程序的冷启动时间可能会有所改善。
Use AppDomains Efficiently
有效地使用AppDomains
If possible, load assemblies into a domain-neutral code area to make sure that the native image, if one exists, is used in all AppDomains created in the application.
如果可能,将程序集加载到域中性代码区域,以确保在应用程序中创建的所有AppDomain中使用本机映像(如果存在)。
For the best performance, enforce efficient cross-domain communication by reducing cross-domain calls. When possible, use calls without arguments or with primitive type arguments.
为获得最佳性能,请通过减少跨域调用来实施高效的跨域通信。如果可能,请使用不带参数的调用或使用基本类型参数。
Use the NeutralResourcesLanguage Attribute
使用NeutralResourcesLanguage属性
Use the NeutralResourcesLanguageAttribute to specify the neutral culture for the ResourceManager. This approach avoids unsuccessful assembly lookups.
使用NeutralResourcesLanguageAttribute为ResourceManager指定中性文化。这种方法避免了不成功的程序集查找。
Use the BinaryFormatter Class for Serialization
使用BinaryFormatter类进行序列化
If you must use serialization, use the BinaryFormatter class instead of the XmlSerializer class. The BinaryFormatter class is implemented in the Base Class Library (BCL) in the mscorlib.dll assembly. The XmlSerializer is implemented in the System.Xml.dll assembly, which might be an additional DLL to load.
如果必须使用序列化,请使用BinaryFormatter类而不是XmlSerializer类。 BinaryFormatter类在mscorlib.dll程序集中的基类库(BCL)中实现。 XmlSerializer在System.Xml.dll程序集中实现,该程序集可能是要加载的其他DLL。
If you must use the XmlSerializer class, you can achieve better performance if you pre-generate the serialization assembly.
如果必须使用XmlSerializer类,则可以在预生成序列化程序集时获得更好的性能。
Configure ClickOnce to Check for Updates After Startup
启动后配置ClickOnce以检查更新
If your application uses ClickOnce, avoid network access on startup by configuring ClickOnce to check the deployment site for updates after the application starts.
如果您的应用程序使用ClickOnce,请通过配置ClickOnce以在应用程序启动后检查部署站点是否有更新来避免启动时的网络访问。
If you use the XAML browser application (XBAP) model, keep in mind that ClickOnce checks the deployment site for updates even if the XBAP is already in the ClickOnce cache. For more information, see ClickOnce Security and Deployment.
如果您使用XAML浏览器应用程序(XBAP)模型,请记住,即使XBAP已在ClickOnce缓存中,ClickOnce也会检查部署站点是否有更新。有关更多信息,请参阅ClickOnce安全性和部署。
Configure the PresentationFontCache Service to Start Automatically
将PresentationFontCache服务配置为自动启动
The first WPF application to run after a reboot is the PresentationFontCache service. The service caches the system fonts, improves font access, and improves overall performance. There is an overhead in starting the service, and in some controlled environments, consider configuring the service to start automatically when the system reboots.
重启后运行的第一个WPF应用程序是PresentationFontCache服务。该服务缓存系统字体,改进字体访问并提高整体性能。启动服务会产生开销,在某些受控环境中,请考虑将服务配置为在系统重新启动时自动启动。
Set Data Binding Programmatically
以编程方式设置数据绑定
Instead of using XAML to set the DataContext declaratively for the main window, consider setting it programmatically in the OnActivated method.
而不是使用XAML以声明方式为主窗口设置DataContext,请考虑在OnActivated方法中以编程方式设置它。
#2
2
The startup time of a WPF Application can be much faster if you use Framework 3.51 and not 3.5 or 3.0. The 3.51 is really an improvement.
如果使用Framework 3.51而不是3.5或3.0,WPF应用程序的启动时间会快得多。 3.51真的是一个改进。
#3
0
What helped me the most from the excellent article that Stuart links to was the XmlSerializer trick. That really shaved up quite a few seconds. Furthermore don't underestimate defragmenting your HD :-)
从Stuart链接的优秀文章中获得最大帮助的是XmlSerializer技巧。真的刮了几秒钟。此外,不要低估你的高清碎片整理:-)
#4
0
The most useful advice on fixing WPF startup performance I've ever seen was given in this other question: run "ngen update" in every framework folder.
关于修复我见过的WPF启动性能的最有用的建议是在另一个问题中给出的:在每个框架文件夹中运行“ngen update”。
It seems that Microsoft can't keep their ngen cache up-to-date, which results in your application pretty much recompiling half the .NET framework every single startup.
似乎微软无法使他们的ngen缓存保持最新状态,这导致您的应用程序在每次启动时都会重新编译.NET框架的一半。
Hard to believe, but seems to be true.
很难相信,但似乎是真的。
#5
0
This is an old thread, but I've ended up here several times while trying to fix a startup performance issue with WPF apps on my Win10 system, so I thought I'd state an answer which may help others - an answer that takes a horrible 5 second startup time for all WPF apps on this system down to just a few milliseconds. Remove the nVidia "3d Vision" driver. I have a GeForce GTX 650 card, and the "3d Vision" driver doesn't seem to offer anything useful, so removing it is no problem for me. The VisualStudio2015 performance analysis tool finally helped show that almost all the 5 second startup time was spent IDLE after a call through nvapi64.dll - the nVidia driver. Wow.
这是一个老线程,但我在Win10系统上试图用WPF应用程序修复启动性能问题时已经好几次了,所以我想我会说出一个可以帮助其他人的答案 - 这个答案需要一个这个系统上所有WPF应用的可怕5秒启动时间只有几毫秒。删除nVidia“3d Vision”驱动程序。我有一块GeForce GTX 650卡,“3d Vision”驱动程序似乎没有提供任何有用的东西,所以删除它对我来说没问题。 VisualStudio2015性能分析工具最终帮助显示,在通过nvapi64.dll(nVidia驱动程序)调用后,几乎所有5秒的启动时间都花费在IDLE上。哇。