WPF 优化 EnsureHandle 启动性能
本文将记录一个在 WPF 应用程序启动过程中的性能优化点。如果一个窗口需要设置 WindowStyle 属性,那么在窗口 EnsureHandle 之前,设置 WindowStyle 属性将会比在 EnsureHandle 之后设置快不少
在 dotTrace 里的一次测量在窗口 EnsureHandle 之后设置 WindowStyle 属性的时间大概是 200 毫秒,这个时间在启动过程中可以被认为是非常长的时间,而且这还是一个在 UI 线程上的时间。以下是 dotTrace 测量结果

可以看到在窗口 EnsureHandle 之后设置 WindowStyle 属性,需要等待 Win32 窗口的响应。再阅读 WPF 源代码,可以看到在窗口 EnsureHandle 之后设置 WindowStyle 属性,就需要等待 HwndStyleManager 的 Dispose 方法。以下是 WPF 的源代码

看起来这是非常合理的耗时,在 Win32 窗口创建出来之后,也就是对应 EnsureHandle 拿到窗口句柄之后,这时如果设置 WindowStyle 属性,就需要同步给到 Win32 窗口。为了同步设置给到 Win32 窗口,自然就需要等待 Win32 窗口处理了,对应的就是以上代码的等待渲染线程挂载窗口的一次渲染逻辑。这里需要说明的是上文说的等待渲染线程挂载窗口的一次渲染逻辑是我的猜测,根据 wpfgfx_cor3.dll 以及 SyncFlush 方法进行猜测的
在 EnsureHandle 之前设置 WindowStyle 则可以规避以上路径从而提升性能。提升性能的原因是在 EnsureHandle 之前,也就是 Win32 窗口创建之前,对 WindowStyle 的赋值走的是一个简单的属性赋值,毫无性能损耗。在真正创建窗口时,才读取 WindowStyle 属性,根据属性去创建 Win32 窗口。由于 WPF 应用本来就需要创建 Win32 窗口,也就是此时对 WindowStyle 的设置本身是不影响 Win32 窗口的创建的,换句话说就是在 Win32 窗口创建之前设置 WindowStyle 约等于免费
那在启动完成之后,窗口渲染完成之后设置 WindowStyle 呢?此时基本上不需要等待渲染,设置 WindowStyle 也就是一个 Win32 函数调用的损耗,大概测量时间在 30ms 左右。也就是说只有在启动过程中,想要做性能优化,才需要关注 EnsureHandle 之前设置 WindowStyle 属性。本文以上测试由 lsj 提供
WPF 优化 EnsureHandle 启动性能的更多相关文章
- dotnet 使用 Crossgen2 对 DLL 进行 ReadyToRun 提升启动性能
		我对几个应用进行严格的启动性能评估,对比了在 .NET Framework 和 dotnet 6 下的应用启动性能,非常符合预期的可以看到,在用户的设备上,经过了 NGen 之后的 .NET Fram ... 
- iOS App 启动性能优化
		1. App启动过程 解析Info.plist 加载相关信息,例如如闪屏 沙箱建立.权限检查 Mach-O加载 如果是胖二进制文件,寻找合适当前CPU类别的部分 加载所有依赖的Mach-O文件(递归调 ... 
- Android性能优化-App启动优化
		原文地址:https://developer.android.com/topic/performance/launch-time.html#common 通常用户期望app响应和加载速度越快越好.一个 ... 
- Windows 程序启动性能优化(先载入EXE,后载入DLL,只取有限的代码载入内存,将CPU的IP指向程序的入口点)
		一.重定位链接时重定位:目标文件一般由多个节组成,编译器在编译每个目标文件时一般都是从0地址开始生成代码.当多个代码节合成一个代码段时,需要根据其在最终代码段中的位置做出调整.同时,链接器需要对已经解 ... 
- 2019-8-31-dotnet-启动-JIT-多核心编译提升启动性能
		title author date CreateTime categories dotnet 启动 JIT 多核心编译提升启动性能 lindexi 2019-08-31 16:55:58 +0800 ... 
- dotnet 启动 JIT 多核心编译提升启动性能
		用2分钟提升十分之一的启动性能,通过在桌面程序启动 JIT 多核心编译提升启动性能 在 dotnet 可以通过让 JIT 进行多核心编译提升软件的启动性能,在默认托管的 ASP.NET 程序是开启的, ... 
- 通过 SMB 直通优化文件服务器的性能
		https://technet.microsoft.com/zh-cn/library/hh831487.aspx Windows Server 2012 内置新增功能,称为 SMB 直通,用来支持使 ... 
- java gc的工作原理、如何优化GC的性能、如何和GC进行有效的交互
		java gc的工作原理.如何优化GC的性能.如何和GC进行有效的交互 一个优秀的Java 程序员必须了解GC 的工作原理.如何优化GC的性能.如何和GC进行有效的交互,因为有一些应用程序对性能要求较 ... 
- 【转】利用TCMalloc优化Nginx的性能
		From: http://www.linuxidc.com/Linux/2013-04/83197.html TCMalloc的全称是 Thread-Caching Malloc,是谷歌开发的开源工具 ... 
- 【原创】构建高性能ASP.NET站点 第七章 如何解决内存的问题(前中篇)—托管资源优化—监测CLR性能
		原文:[原创]构建高性能ASP.NET站点 第七章 如何解决内存的问题(前中篇)-托管资源优化-监测CLR性能 构建高性能ASP.NET站点 第七章 如何解决内存的问题(前中篇)—托管资源优化—监测C ... 
随机推荐
- 记录--三分钟打造自己专属的uni-app工具箱
			这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 介绍 可曾想过我们每次创建新项目,或者换地方写程序,都要把之前写过的工具类找出来又要复制粘贴一遍有些麻烦,尤其是写uni-app自定义模板 ... 
- Ficow 陪你看 WWDC 2022
			本文首发于 Ficow Shen's Blog,原文地址: WWDC22 - Xcode 14 新特性. 内容概览 前言 用好过滤器 Recap,节约你的宝贵时间 Essential,取其精华 必看内 ... 
- 开发进阶系列:Java网络通信编程从基础到框架
			一 基本概念 IO(BIO)和NIO的区别:其本质就是阻塞和非阻塞的区别. 阻塞:应用程序在获取网络数据的时候,如果网络传输数据很慢,那程序就一直等着,直到传输完毕为止. 非阻塞:应用程序直接可以获 ... 
- WinAppSDK / WinUI3 项目无法使用 SystemEvents 的问题
			SystemEvents 是一个开发 win32 窗口项目很常用的类,其中封装了一些常用的系统广播消息.在 WinUI3 项目中,SystemEvents 事件经常无法触发,简单排查了一下原因. Sy ... 
- KingbaseES V8R6集群备份恢复案例之---备份初始化“can not find primary node”故障
			案例说明: KingbaseES V8R6集群,备库作为repo-path节点,建立类型为'cluster'模式的备份,在执行sys_backup.sh init时,出现"can not f ... 
- UE427-C++实现摄像机视角的移动,类似开镜效果
			教程 方法 调整相机视野和弹簧臂的长度 //自带的tick函数内 需要使用DeltaTime if (bZoomIn) { ZoomFactor += DeltaTime / 0.5f; } else ... 
- Linux电脑如何下载QGIS?
			本文介绍在Linux操作系统Ubuntu版本中,通过命令行的方式,配置QGIS软件的方法. 在Ubuntu等Linux系统中,可以对空间信息加以可视化的遥感.GIS软件很少,比如ArcGIS下 ... 
- 关于Guava Cache 需要注意的几点
			一.元素过期策略 expireAfterWrite(long duration, TimeUnit unit):在元素[写入]或者[值更新]后的一段时间之后,自动移除元素. 当duration=0时, ... 
- ArrayList,LinkedList,Vector三者的区别
			List 中元素是有序的,元素可以重复,因为该集合体有索引 ArrayList: 底层数据结构是数组,查询快,增删慢. 线程不安全,效率高. 当元素放满了后,默认以原长度的 50%+1 的长度加长集合 ... 
- 6 JavaScript条件判断
			6 条件判断 除了HTML以外. 几乎所有的编程语言都有条件判断的功能. 比如, python, 我们用if语句来做条件判断. 到了javascript中也是一样的, 也使用javascript来做条 ... 
