关于 maui-performance
.NET MAUI 性能优化技能,面向构建 MAUI 应用的开发者,涵盖性能分析、布局与绑定优化,以及启动、修剪和 NativeAOT 调优。
主要功能
- 01使用 dotnet-trace 和 PerfView 分析性能
- 02启用编译绑定并减少反射
- 03优化布局与列表测量
- 04调整图像尺寸和缓存
- 05减少启动工作并启用修剪与 NativeAOT
适用场景
- 01定位 MAUI 应用的 CPU 与内存开销
- 02加快页面布局和列表渲染
- 03为修剪或 NativeAOT 发布检查兼容性
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ davidortinau/ maui-skills --skill maui-performance安装后在 Claude Code 中输入/maui-performance确认已加载。
详细介绍
.NET MAUI 性能优化
性能分析
- dotnet-trace:适用于所有 MAUI 目标平台的跨平台性能分析器。使用以下命令收集跟踪信息:
dotnet-trace collect --process-id <PID> --providers Microsoft-DotNETCore-SampleProfiler - PerfView(仅限 Windows):用于对 WinUI 目标进行深入的内存分配和 CPU 分析。
- 优化前先进行性能分析——测量,而不是猜测。
编译绑定
- 始终在页面/视图上设置
x:DataType,以启用编译绑定。 - 编译绑定比基于反射的绑定快 8–20 倍。
- NativeAOT 和完全裁剪的必要条件——反射绑定在裁剪时会失效。
- 在合理的最高层级(页面或根元素)应用
x:DataType。
<ContentPage xmlns:vm="clr-namespace:MyApp.ViewModels"
x:DataType="vm:MainViewModel">
<Label Text="{Binding Title}" />
</ContentPage>
- 对于
CollectionView/ListView中的DataTemplate,在模板根元素上设置x:DataType:
<DataTemplate x:DataType="model:Item">
<Label Text="{Binding Name}" />
</DataTemplate>
- 尽量减少不必要的绑定:不会变化的静态内容不需要
{Binding}。改用字面值或x:Static。
布局优化
- 避免嵌套的单子元素布局——只有一个子元素的
StackLayout会造成无谓的开销。 - 优先使用
Grid,而非嵌套的StackLayout/VerticalStackLayout——Grid可在单次遍历中完成布局计算。 - 使用
IsVisible="False"隐藏元素,而不是在运行时从元素树中添加或移除。 - 移除不必要的包装容器——每个布局都会增加一次测量/排列遍历。
- 避免使用
AbsoluteLayout,如果使用带行/列定义的Grid就能实现相同效果。 - 在尺寸已知时设置明确的
WidthRequest/HeightRequest,以减少测量遍历。
CollectionView 和 ListView
- 当
CollectionView中的项高度一致时,使用ItemSizingStrategy="MeasureFirstItem"——避免逐项测量。
<CollectionView ItemSizingStrategy="MeasureFirstItem"
ItemsSource="{Binding Items}">
- 新项目优先使用
CollectionView,而不是ListView。 - 保持
DataTemplate视觉树浅层——减少每个项中的嵌套布局。
图像优化
- 让图像尺寸匹配显示分辨率——不要为 200×200 的显示区域加载 4000×3000 的图像。
- 使用
Aspect="AspectFill"或AspectFit,并设置明确的尺寸。 - 缓存下载的图像:在
UriImageSource上使用CachingEnabled="True"(默认值),并设置CacheValidity。 - 使用适合平台的格式(Android 使用 WebP,iOS 使用 HEIF/PNG)。
- 对于图标和简单图形,优先使用 SVG 或基于矢量的字体图标。
资源字典
- 应用级(
App.xaml):多个页面共用的样式、颜色和转换器。 - 页面级:单个页面专用的样式/资源——保持
App.xaml简洁。 - 避免在不同字典中重复定义资源。
- 使用
MergedDictionaries组织大型资源集,避免单个文件过于臃肿。
启动优化
- 尽量减少
App构造函数和MainPage构造函数中的工作。 - 推迟非必要的服务注册——尽可能使用延迟初始化。
- 减少启动时解析的 XAML 页面数量(使用
Shell路由延迟加载)。 - 从
MauiProgram.cs中移除未使用的Handlers/Effects注册。 - 在 Android 上,确保
AndroidManifest.xml不会在启动时强制执行不必要的权限检查。
裁剪
启用 IL 裁剪,以减小应用体积并移除未使用的代码:
<PropertyGroup>
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>full</TrimMode>
</PropertyGroup>
- 进行充分测试——裁剪可能会移除仅通过反射访问的代码。
- 使用
[DynamicDependency]或[UnconditionalSuppressMessage]保留反射目标。 - 编译绑定至关重要——基于反射的绑定会被裁剪掉。
NativeAOT
- NativeAOT 会提前将代码编译为原生代码,以加快启动速度并缩小体积。
- 要求:编译绑定、不受限制的反射为零、代码兼容裁剪。
<PropertyGroup>
<PublishAot>true</PublishAot>
<PublishTrimmed>true</PublishTrimmed>
</PropertyGroup>
- 检查第三方 NuGet 包是否兼容裁剪/AOT。
- 使用
[JsonSerializable]源生成器,而非基于反射的 JSON 序列化。 - 发布前使用 AOT 运行
dotnet publish,确认没有警告。
快速检查清单
- ✅ 所有页面、模板和数据绑定视图都设置了
x:DataType - ✅ 不使用嵌套的单子元素布局
- ✅ 优先使用 Grid,避免嵌套 StackLayouts
- ✅ 图片尺寸适合显示,并启用缓存
- ✅ 在统一大小的 CollectionView 上设置
ItemSizingStrategy="MeasureFirstItem" - ✅ 尽量减少启动时的工作,并将其延后
- ✅ 启用修剪并进行测试
- ✅ 在更改前后使用 dotnet-trace 进行性能分析
评论
支持 Markdown