重要
从 Windows 10 版本 1703(Creators Update)开始, x:DeferLoadStrategy 被 x:Load 属性取代。 使用 x:Load="False" 等效于 x:DeferLoadStrategy="Lazy",但提供根据需要卸载 UI 的功能。 有关详细信息,请参阅 x:Load 属性 。
可以使用 x:DeferLoadStrategy=“Lazy” 优化 XAML 应用的启动或树创建性能。 使用 x:DeferLoadStrategy=“Lazy”时,将延迟创建元素及其子元素,从而减少启动时间和内存成本。 这可用于降低不经常或有条件地显示的元素的成本。 当从代码或 VisualStateManager 中引用该元素时,该元素将被呈现。
但是,XAML 框架对延迟元素的跟踪会将大约 600 字节添加到受影响的每个元素的内存使用情况。 延迟的元素树越大,将节省的启动时间越多,但代价是内存占用量更大。 因此,过度使用此属性可能导致性能下降。
XAML 属性用法
<object x:DeferLoadStrategy="Lazy" .../>
注解
使用 x:DeferLoadStrategy 的限制 如下:
- 因为以后需要查找该元素,必须为该元素定义一个x:Name。
- 只能推迟派生自 UIElement 或 FlyoutBase 的类型。
- 不能延迟 Page、 UserControl 或 DataTemplate 中的根元素。
- 不能延迟 ResourceDictionary 中的元素。
- 你不能延迟加载通过 XamlReader.Load 的松散 XAML。
- 移动父元素将清除尚未实现的任何元素。
可以通过几种不同的方式实现延迟元素:
- 使用在元素上定义的名称调用 FindName 。
- 请使用在元素上定义的名称来调用GetTemplateChild。
- 在 VisualState 中,使用面向延迟元素的 Setter 或 Storyboard 动画。
- 以任何 情节提要中的延迟元素为目标。
- 使用针对延迟元素的绑定。
注意:一旦元素的实例化启动,它就会在 UI 线程上创建,因此,如果在一次创建太多内容时,它可能会导致 UI 停滞不前。
以前面列出的任意方式创建延迟元素后,会发生以下几件事:
- 引发元素上的 Loaded 事件。
- 评估元素上的所有绑定。
- 如果您已注册接收与包含延迟元素的属性相关的属性更改通知,则会触发通知。
你可以嵌套延迟执行的元素,但它们必须从最外层元素依次加载。 如果在实现父元素之前尝试实现子元素,则会引发异常。
通常,我们建议延迟在第一帧中不可查看的元素。 寻找可推迟候选项的一个有效准则是查找正在使用折叠可见性创建的元素。 此外,由用户交互触发的 UI 是查找可以延迟的元素的好位置。
请谨慎地推迟 ListView 中的元素,因为它会减少启动时间,但也可能会根据所创建的内容降低平移性能。 如果要提高平移性能,请参阅 {x:Bind} 标记扩展 和 x:Phase 属性 文档。
如果 x:Phase 属性 与 x:DeferLoadStrategy 结合使用,则当实现元素或元素树时,绑定将应用到当前阶段并包括当前阶段。 为 x:Phase 指定的阶段不会影响或控制元素的延迟。 当列表项作为平移的一部分回收时,实现的元素的行为方式与其他活动元素相同,并且编译的绑定({x:Bind} 绑定)使用相同的规则进行处理,包括分段。
一般准则是衡量应用前后的性能,以确保获得所需的性能。
Example
<Grid x:Name="DeferredGrid" x:DeferLoadStrategy="Lazy">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Rectangle Height="100" Width="100" Fill="#F65314" Margin="0,0,4,4" />
<Rectangle Height="100" Width="100" Fill="#7CBB00" Grid.Column="1" Margin="4,0,0,4" />
<Rectangle Height="100" Width="100" Fill="#00A1F1" Grid.Row="1" Margin="0,4,4,0" />
<Rectangle Height="100" Width="100" Fill="#FFBB00" Grid.Row="1" Grid.Column="1" Margin="4,4,0,0" />
</Grid>
<Button x:Name="RealizeElements" Content="Realize Elements" Click="RealizeElements_Click"/>
private void RealizeElements_Click(object sender, RoutedEventArgs e)
{
// This will realize the deferred grid.
this.FindName("DeferredGrid");
}