다음을 통해 공유


x:Load 특성

x:Load를 사용하여 XAML 앱의 시작, 시각적 트리 만들기 및 메모리 사용을 최적화할 수 있습니다. x:Load를 사용하면 요소가 로드되지 않을 때 메모리가 해제되고 내부적으로 작은 자리 표시자가 시각적 트리에서 해당 위치를 표시하는 데 사용된다는 점을 제외하고 Visibility와 유사한 시각적 효과가 있습니다.

x:Load로 특성이 지정된 UI 요소는 코드를 통해 또는 x:Bind 식을 사용하여 로드 및 언로드할 수 있습니다. 이는 드물게 또는 조건부로 표시되는 요소의 비용을 줄이는 데 유용합니다. Grid 또는 StackPanel과 같은 컨테이너에서 x:Load를 사용하면 컨테이너와 모든 자식이 그룹으로 로드되거나 언로드됩니다.

XAML 프레임워크에서 지연된 요소를 추적하면 x:Load로 특성이 지정된 각 요소의 메모리 사용량에 약 600바이트가 추가되어 자리 표시자를 고려합니다. 따라서 성능이 실제로 저하되는 범위까지 이 특성을 과도하게 사용할 수 있습니다. 숨겨야 하는 요소에만 사용하는 것이 좋습니다. 컨테이너에서 x:Load를 사용하는 경우 오버헤드는 x:Load 특성이 있는 요소에 대해서만 지불됩니다.

중요합니다

x:Load 특성은 Windows 10 버전 1703(크리에이터스 업데이트)부터 사용할 수 있습니다. x:Load를 사용하려면 Visual Studio 프로젝트의 최소 버전이 Windows 10 크리에이터 업데이트(10.0, 빌드 15063) 여야 합니다.

XAML 특성 사용

<object x:Load="True" .../>
<object x:Load="False" .../>
<object x:Load="{x:Bind Path.to.a.boolean, Mode=OneWay}" .../>

요소 불러오기

요소를 로드하는 방법에는 여러 가지가 있습니다.

  • x:Bind 식을 사용하여 부하 상태를 지정합니다. 식을 로드하려면 true 를 반환하고 요소를 언로드하려면 false 를 반환해야 합니다.
  • 요소에 정의한 이름으로 FindName 을 호출합니다.
  • 요소에 정의한 이름으로 GetTemplateChild 를 호출합니다.
  • VisualState에서 x:Load 요소를 대상으로 하는 Setter 또는 Storyboard 애니메이션을 사용합니다.
  • Storyboard에서 언로드된 요소를 대상으로 지정합니다.

비고

요소의 인스턴스화가 시작되면 UI 스레드에서 만들어지므로 한 번에 너무 많이 만들어지면 UI가 더듬거릴 수 있습니다.

이전에 나열된 방법으로 지연된 요소가 만들어지면 다음과 같은 몇 가지 상황이 발생합니다.

  • 요소의 Loaded 이벤트가 발생합니다.
  • x:Name 필드가 설정됩니다.
  • 요소의 모든 x:Bind 바인딩이 적용됩니다.
  • 지연된 요소가 포함된 속성에 대한 속성 변경 알림을 받도록 등록한 경우 알림이 발생합니다.

요소 언로드

요소를 언로드하려면 다음을 수행합니다.

  • x:Bind 식을 사용하여 부하 상태를 지정합니다. 식을 로드하려면 true 를 반환하고 요소를 언로드하려면 false 를 반환해야 합니다.
  • Page 또는 UserControl에서 UnloadObject 를 호출하고 개체 참조를 전달합니다.
  • Microsoft.UI.Xaml.Markup.XamlMarkupHelper.UnloadObject를 호출하고 개체 참조를 전달합니다.

개체가 언로드될 때 트리에서 플레이스홀더로 대체됩니다. 개체 인스턴스는 모든 참조가 해제될 때까지 메모리에 유지됩니다. Page/UserControl의 UnloadObject API는 x:Name 및 x:Bind에 대해 codegen이 보유한 참조를 해제하도록 설계되었습니다. 앱 코드에 추가 참조를 보유하는 경우 해당 참조도 릴리스해야 합니다.

요소가 언로드되면 요소와 연결된 모든 상태가 삭제되므로 x:Load를 최적화된 버전의 Visibility로 사용하는 경우 바인딩을 통해 모든 상태가 적용되거나 Loaded 이벤트가 발생할 때 코드에 의해 다시 적용됩니다.

제한 사항

x:Load 사용에 대한 제한 사항은 다음과 같습니다.

  • 나중에 요소를 찾는 방법이 필요하므로 요소의 x:Name 을 정의해야 합니다.
  • UIElement 또는 FlyoutBase에서 파생되는 형식에만 x:Load를 사용할 수 있습니다.
  • Page, UserControl 또는 DataTemplate의 루트 요소에는 x:Load를 사용할 수 없습니다.
  • ResourceDictionary의 요소에 x:Load를 사용할 수 없습니다.
  • XamlReader.Load와 함께 로드된 느슨한 XAML에서는 x:Load를 사용할 수 없습니다.
  • 부모 요소를 이동하면 로드되지 않은 요소가 지워지게 됩니다.

비고

중첩된 요소에 x:Load를 사용할 수 있지만 가장 바깥 쪽 요소에서 구현해야 합니다.  부모가 실현되기 전에 자식 요소를 실현하려고 하면 예외가 발생합니다.

일반적으로 첫 번째 프레임에서 볼 수 없는 요소를 연기하는 것이 좋습니다. 지연할 후보를 찾기 위한 좋은 지침은 축소된 가시성으로 생성되는 요소를 찾는 것입니다. 또한 사용자 상호 작용에 의해 트리거되는 UI는 연기할 수 있는 요소를 찾는 데 적합합니다.

시작 시간이 줄어들지만 만드는 항목에 따라 이동 성능이 저하될 수 있으므로 ListView에서 요소를 지연시키는 것을 주의해야 합니다. 이동 성능을 향상시키려면 {x:Bind} 태그 확장x:Phase 특성 설명서를 참조하세요.

x:Phase 특성x:Load와 함께 사용되는 경우 요소 또는 요소 트리가 실현되면 바인딩이 현재 단계까지 적용됩니다. x:Phase에 지정된 단계는 요소의 로드 상태에 영향을 주거나 제어합니다. 목록 항목이 이동의 일부로 재활용되면 실현된 요소는 다른 활성 요소와 동일한 방식으로 동작하며 컴파일된 바인딩({x:Bind} 바인딩)은 단계적 처리를 포함하여 동일한 규칙을 사용하여 처리됩니다.

일반적인 지침은 원하는 성능을 얻기 위해 전후에 앱의 성능을 측정하는 것입니다.

x :Load 를 요소에 추가할 때 성능 외에 동작 변경을 최소화하기 위해 x:Bind 바인딩은 x: Load를 사용하는 요소가 없는 것처럼 정상적인 시간에 계산됩니다. 예를 들어 OneTime x:Bind 바인딩은 루트 요소가 로드되면 계산됩니다. x:Bind 바인딩이 계산될 때 요소가 실현되지 않으면 계산된 값이 저장되고 로드될 때 요소에 적용됩니다. 이 동작은 요소가 실현될 때 x:Bind 바인딩이 계산될 것으로 예상한 경우에 놀라운 일이 될 수 있습니다.

Example

<StackPanel>
    <Grid x:Name="DeferredGrid" x:Load="False">
        <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="Orange" Margin="0,0,4,4"/>
        <Rectangle Height="100" Width="100" Fill="Green" Grid.Column="1" Margin="4,0,0,4"/>
        <Rectangle Height="100" Width="100" Fill="Blue" Grid.Row="1" Margin="0,4,4,0"/>
        <Rectangle Height="100" Width="100" Fill="Gold" Grid.Row="1" Grid.Column="1" Margin="4,4,0,0"
                   x:Name="one" x:Load="{x:Bind (x:Boolean)CheckBox1.IsChecked, Mode=OneWay}"/>
        <Rectangle Height="100" Width="100" Fill="Silver" Grid.Row="1" Grid.Column="1" Margin="4,4,0,0"
                   x:Name="two" x:Load="{x:Bind Not(CheckBox1.IsChecked), Mode=OneWay}"/>
    </Grid>

    <Button Content="Load elements" Click="LoadElements_Click"/>
    <Button Content="Unload elements" Click="UnloadElements_Click"/>
    <CheckBox x:Name="CheckBox1" Content="Swap Elements" />
</StackPanel>
// This is used by the bindings between the rectangles and check box.
private bool Not(bool? value) { return !(value==true); }

private void LoadElements_Click(object sender, RoutedEventArgs e)
{
    // This will load the deferred grid, but not the nested
    // rectangles that have x:Load attributes.
    this.FindName("DeferredGrid"); 
}

private void UnloadElements_Click(object sender, RoutedEventArgs e)
{
     // This will unload the grid and all its child elements.
     this.UnloadObject(DeferredGrid);
}