程式慢,只有兩個原因,一個我們寫不好,一個 Xamarin 沒寫好...
而在寫 Xamarin.Forms 時,其實有很多的眉角,可以提升我們App的效能!!
提升效能的同時,當然也能增加使用者體驗。
效能跟許多東西有關連,最最基本的 C# 程式要顧好,
其他關於 Xamrin.Fomrs 的部分,將會在本篇教學會一一提出 ~
開啟 XAML Compiler
XAML 可以在程式內指定使用 XAML Compiler (XAMLC),它可以將 XAML 轉成中介語言 (IL) 來提升效能,
使用 XAMLC 有以下好處:
使用 XAMLC 有以下好處:
- 編譯期間會檢查 XAML 是否有錯誤
- 降低讀取 XAML 元件的時間
- 減少最後產出的檔案大小
using Xamarin.Forms.Xaml; ... [assembly: XamlCompilation (XamlCompilationOptions.Compile)] namespace PhotoApp { ... }
在 Class 加入 XAMLC:
using Xamarin.Forms.Xaml; ... [XamlCompilation (XamlCompilationOptions.Compile)] public class HomePage : ContentPage { ... }
正確的使用 Layout
一個 Layout 可以包含許多的子物件,但如果畫面上只有一個物件,那就不需要用 Layout 了吧!
另外,底下範例利用多個 StackLayout 組出的畫面,也是相當浪費效能的
上面的範例可以選擇用 Grid
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="DisplayImage.HomePage"> <ContentPage.Content> <StackLayout> <Image Source="waterfront.jpg" /> </StackLayout> </ContentPage.Content> </ContentPage>像樓上這樣放就很浪費資源和記憶體,只有一個物件就不需要 Layout了!
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="DisplayImage.HomePage"> <ContentPage.Content> <Image Source="waterfront.jpg" /> </ContentPage.Content> </ContentPage>
另外,底下範例利用多個 StackLayout 組出的畫面,也是相當浪費效能的
<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"> <ContentPage.Content> <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.Content> </ContentPage>
上面的範例可以選擇用 Grid
<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"> <ContentPage.Content> <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.Content> </ContentPage>
開啟 Layout Compression
慎用,Layout Compression 不適用於外觀屬性、互動屬性(例如 BackgrounColor, IsVisible, Rotation, Scale, TranslationX or TranslationY) 要做設定的物件,壓縮過後會造成物件的屬性失效。Layout Compression 主要是針對 Xamarin.Forms 轉回 Native Language 時,做一個扁平化的動作,會將一些不必要的 "層" 去除。
XAML 開啟 LayoutCompression:
<StackLayout CompressedLayout.IsHeadless="true"> <StackLayout CompressedLayout.IsHeadless="true" ...> <AbsoluteLayout CompressedLayout.IsHeadless="true" ...> ... </AbsoluteLayout> </StackLayout> ... </StackLayout>
也可以在 C# 內開啟:
CompressedLayout.SetIsHeadless(stackLayout, true);
使用 Fast Renderers
在 Android 專案內的 MainActivity.cs,Forms.Init 之前加入這行
Forms.SetFlags("FastRenderers_Experimental");
官方說,Xamarin.fomrs 2.4 版本會針對以下物件做效能的優化
- Button
- Image
- Label
尤其在 ListView 會有顯著的效能提升,若 ListView 有上千筆資料,有可能讓效能提升兩倍以上,資料捲動時更順暢。
減少不必要的 Binding
如果只是簡單的要設定 Button.Text = "Hello" 時,就不要假會還用 ViewModel 去做屬性值 Binding !
相關 Binding 的教學可以從這篇開始看到 MVVM。
相關 Binding 的教學可以從這篇開始看到 MVVM。
Layout 的效能調教
使用 Layout 時有一些細節
- 減少 Layout 的層數,盡量用 Margin 去安排物件的位置。
- 使用 Grid 時,請盡量少用 "Auto" size (Row 和 Column 可以設定成 Auto,依照 Cell 內物件的大小計算其寬高)。
- 除非必要,盡量少用 VerticalOptions 和 HorizontalOptions,設定這兩個值會增加額外的運算。
- 避免使用 RelativeLayout。
- 使用 AbsoluteLayout 時,避免使用 AbsoluteLayout.AutoSize。
- 使用 StackLayout 時,確定只有一個子物件設定為 LayoutOtpions.Expand,同時設定兩個物件為 Expand 會太浪費效能。
- 除非必要,不要經常性的更新 "Label",每次的更新都會重新計算 Label 的大小。
- 除非必要,不要設定 Label.VerticalTextAlignment。
- 請經常將 Label 的 LineBreakMode 設定為 NoWrap。
- AbsoluteLayout 的效能是最好的。
ListView 的效能調教
- ItemSource 請綁定 IList<T> 類型的資料,不要綁 IEnumerable<T>,IEnumeralble 不支援隨機存取。
- 盡量使用內建的 cell (像是 TextCell/ SwitchCell),會比 ViewCell 的效能好
- 越少物件越好,舉例來說,若有多行文字要顯示,可以用一個 Label 搭配 FormattedString,而不是放多個 Label。
- 如果每一筆的資料型態不一樣,請改用 TableView。
- 在 Android,不要在 ListView 被實體化後才更改其顏色或是外觀。
- 除了 LayoutOptions.Fill,其它盡量少用 (Fill 是運算速度最快的)。
- 不要把 ListView 再放入 ScrollView 內,ListView 本身就有實作 Scroll 的功能。
- 若你的 Cell 很複雜,建議先做 Custom renderer。
減少 Resource Dictinonary 的大小
若有共用的 ResoruceDictionary,就將她放在 Application 內,不要在各頁重複寫
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Resources.App"> <Application.Resources> <ResourceDictionary> <Style x:Key="HeadingLabelStyle" TargetType="Label"> <Setter Property="HorizontalOptions" Value="Center" /> <Setter Property="FontSize" Value="Large" /> <Setter Property="TextColor" Value="Red" /> </Style> </ResourceDictionary> </Application.Resources> </Application>
相信大家可以讓 Xamarin App 效能更好一點了!!
(下周休刊)
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。