shuhelohelo’s blog

Xamarin.Forms多めです.

Xamarin.Formsアプリのパフォーマンス向上について

docs.microsoft.com

UIについてだけでなく,様々な点についてパフォーマンス向上に関するTIPSが書かれている.

  • 子要素が1つだけなのにStackLayoutを使わない
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DisplayImage.HomePage">
    <StackLayout>
        <Image Source="waterfront.jpg" />
    </StackLayout>
</ContentPage>
  • できるだけ階層は浅くする

同じ見た目を実現できるのであれば,できるだけ階層は浅くする.

階層が深いと計算の負荷も高くなる.

階層深い:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Details.HomePage"
             Padding="0,20,0,0">
    <StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Name:" />
            <Entry Placeholder="Enter your name" />
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Age:" />
            <Entry Placeholder="Enter your age" />
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Occupation:" />
            <Entry Placeholder="Enter your occupation" />
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Address:" />
            <Entry Placeholder="Enter your address" />
        </StackLayout>
    </StackLayout>
</ContentPage>

階層浅い:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Details.HomePage"
             Padding="0,20,0,0">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="30" />
            <RowDefinition Height="30" />
            <RowDefinition Height="30" />
            <RowDefinition Height="30" />
        </Grid.RowDefinitions>
        <Label Text="Name:" />
        <Entry Grid.Column="1" Placeholder="Enter your name" />
        <Label Grid.Row="1" Text="Age:" />
        <Entry Grid.Row="1" Grid.Column="1" Placeholder="Enter your age" />
        <Label Grid.Row="2" Text="Occupation:" />
        <Entry Grid.Row="2" Grid.Column="1" Placeholder="Enter your occupation" />
        <Label Grid.Row="3" Text="Address:" />
        <Entry Grid.Row="3" Grid.Column="1" Placeholder="Enter your address" />
    </Grid>
</ContentPage>
  • 階層は浅くする.
  • Gridのサイズ指定でAutoはできるだけ少なくする.
  • VerticalOptionsとHorizontalOptionsは必要なときだけ設定する.デフォルト値をわざわざ設定しなおすだけでも負荷になる.
  • RelativeLayoutはできるだけ使わない
  • AbsoluteLayoutを使うときはAbsoluteLayout.AutoSizeをできるだけ使わない
  • StackLayoutを使うとき,LayoutOptions.Expandsを指定する子要素は1つだけにする.
  • Layoutクラスのメソッドを使わないこと.
  • Labelを不必要に更新しないこと.Labelのサイズが変わったときにレイアウトが再計算されるため.
  • Label.VerticalTextAlignmentは必要なとき以外は設定しない.
  • 可能な限りLineBreakModeを使って,折返しが発生しないようにする.レイアウトの再計算が発生するため.
  • AsynchronousなAPIをできるだけ使うこと.UIスレッドがブロックされずにすむ
  • Asynchronousな処理によるUIの更新の際は例外の発生に気をつけること.
  • ただし,ListView.ItemsSourceプロパティの更新は自動的にUIスレッド上で行われるので大丈夫.
  • すべてのデータバインディングによる更新はUIスレッド上で行われるので大丈夫.
  • Shellを使え.
  • ShellはViewの生成をオンデマンドで行うこともできるので,起動時の負荷が小さい
  • ListViewの代わりにCollectionViewを使え
  • Visual Treeのサイズを小さくする
<StackLayout>
    <StackLayout Padding="20,20,0,0">
        <Label Text="Hello" />
    </StackLayout>
    <StackLayout Padding="20,20,0,0">
        <Label Text="Welcome to the App!" />
    </StackLayout>
    <StackLayout Padding="20,20,0,0">
        <Label Text="Downloading Data..." />
    </StackLayout>
</StackLayout>

<StackLayout Padding="20,35,20,20" Spacing="25">
  <Label Text="Hello" />
  <Label Text="Welcome to the App!" />
  <Label Text="Downloading Data..." />
</StackLayout>
  • ApplicationのResourceDictionaryのサイズを小さくする
  • 特定のページでしか使わない設定は,ApplicationではなくContentPage内のResourceDictionaryで設定すること.