布局压缩

为了提升页面呈现性能,布局压缩从可视化树中删除指定的布局。 本文介绍如何启用布局压缩及其带来的好处。

概述

Xamarin.Forms 使用两个递归方法调用系列执行布局:

  • 布局以页面开头的可视化树顶部,它继续浏览可视化树的所有分支,以包含页面上的每个视觉元素。 其他元素的父元素负责调整其子级,并定位其子元素相对于自身。
  • 无效是页面上元素发生更改触发新布局周期的过程。 当元素不再具有正确的大小或位置时,这些元素被视为无效。 每当其中一个子元素更改大小时,都会提醒具有子元素的可视化树中的每个元素。 因此,可视化树中元素大小的更改可能导致树出现连锁变化。

有关 Xamarin.Forms 如何执行布局的详细信息,请参阅创建自定义布局

布局过程的结果是本机控件的层次结构。 然而,这种层次结构包括额外的容器呈现器和平台呈现器的包装器,进一步扩充了视图层次结构嵌套。 嵌套级别越深,Xamarin.Forms 显示页面所需的工作量就越大。 对于复杂的布局,视图层次结构既可以很深,也可以很广,具有多个嵌套级别。

例如,请考虑下面这个用于登录 Facebook 的示例应用程序按钮:

Facebook 按钮

该按钮被指定为自定义控件,其 XAML 视图层次结构如下:

<ContentView ...>
    <StackLayout>
        <StackLayout ...>
            <AbsoluteLayout ...>
                <Button ... />    
                <Image ... />
                <Image ... />
                <BoxView ... />
                <Label ... />
                <Button ... />
            </AbsoluteLayout>
        </StackLayout>
        <Label ... />
    </StackLayout>    
</ContentView>

可以使用实时可视化树检查生成的嵌套视图层次结构。 在 Android 上,嵌套视图层次结构包含 17 个视图:

查看 Facebook 层次结构按钮

布局压缩适用于 iOS 和 Android 平台上的 Xamarin.Forms 应用程序,旨在通过从可视化树中移除指定布局来合并视图嵌套,从而提高页面渲染性能。 这带来的性能优势因页面复杂性、要使用的操作系统版本以及运行应用的设备而异。 不过,在旧设备上实现的性能提升最大。

注意

本文主要介绍在 Android 上应用布局压缩的结果,但同样适用于 iOS。

布局压缩

在 XAML 中,可以通过将布局类上的 CompressedLayout.IsHeadless 附加属性设置为 true 来启用布局压缩:

<StackLayout CompressedLayout.IsHeadless="true">
  ...
</StackLayout>   

或者,也可以将布局实例指定为 CompressedLayout.SetIsHeadless 方法的第一个参数,从而在 C# 中启用它:

CompressedLayout.SetIsHeadless(stackLayout, true);

重要

由于布局压缩会将布局从可视化树中移除,因此不适用于具有可视化外观或可获得触控输入的布局。 因此,设置了 VisualElement 属性(如 BackgroundColorIsVisibleRotationScaleTranslationXTranslationY)或接受手势的布局不适合进行布局压缩。 不过,在设置视觉外观属性或接受手势的布局上启用布局压缩不会导致生成或运行时错误。 布局压缩将被应用,视觉外观属性和手势识别将以无提示的方式失败。

对于 Facebook 按钮,可以在三个布局类上启用布局压缩:

<StackLayout CompressedLayout.IsHeadless="true">
    <StackLayout CompressedLayout.IsHeadless="true" ...>
        <AbsoluteLayout CompressedLayout.IsHeadless="true" ...>
            ...
        </AbsoluteLayout>
    </StackLayout>
    ...
</StackLayout>  

在 Android 上,这会产生一个由 14 个视图组成的嵌套视图层次结构:

使用布局压缩查看 Facebook 层次结构按钮

与最初的由 17 个视图组成的嵌套视图层次结构相比,视图数量减少了 17%。 虽然这种减少看似微不足道,但整个页面的视图减少可能更为显著。

快速呈现器

快速呈现器通过合并生成的本机视图层次结构,降低了 Android 上 Xamarin.Forms 控件的扩充和呈现成本。 这样一来,创建的对象就变少了,相应地也降低了可视化树的复杂性和内存使用率,从而进一步提升了性能。 有关快速呈现器的详细信息,请参阅 快速呈现器

对于示例应用程序中的 Facebook 按钮,结合布局压缩和快速呈现器,可生成由 8 个视图组成的嵌套视图层次结构:

使用布局压缩和快速呈现器查看 Facebook 层次结构按钮

与最初的由 17 个视图组成的嵌套视图层次结构相比,减少了 52%。

示例应用程序包含从实际应用程序中提取的页面。 在没有布局压缩和快速呈现器的情况下,Android 上的页面会产生一个由 130 个视图组成的嵌套视图层次结构。 在适当的布局类上启用快速呈现器和布局压缩后,嵌套视图层次结构减少到 70 个视图,减少了 46%。

总结

为了提升页面呈现性能,布局压缩从可视化树中删除指定的布局。 这带来的性能优势因页面复杂性、要使用的操作系统版本以及运行应用的设备而异。 不过,在旧设备上实现的性能提升最大。