Xamarin.Forms Shell + производительность загрузки вкладки ReactiveUI (на Android) - PullRequest
0 голосов
/ 03 октября 2019

Я уже некоторое время тестирую ReactiveUI (очень рекомендую!), Но недавно натолкнулся на проблему с производительностью, в которой я не уверен, что это связано с самим ReactiveUI (учитывая, что он, кажется, полагается на отражение в некоторых вещах) ИЛИ оболочка приложения Xamarin.Forms. Существует явная задержка при переходе на вкладку, содержимое которой имеет привязки ReactiveUI, это более заметно при работе на эмуляторе, но также может наблюдаться и на реальном устройстве (протестировано на устройствах Android 6 и Android 9). Есть ли стратегия для улучшения производительности вкладки App Shell? Проблема производительности возникает только при первой загрузке вкладки. Соответствующий код ниже (упрощенный пример на основе базового шаблона визуальной студии App Shell):

AppShell.Xaml

<?xml version="1.0" encoding="UTF-8"?>
<Shell xmlns="http://xamarin.com/schemas/2014/forms" 
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:d="http://xamarin.com/schemas/2014/forms/design"
       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
       mc:Ignorable="d"
       xmlns:local="clr-namespace:ReactiveXam.Views"
       Title="ReactiveXam"
        x:Class="ReactiveXam.AppShell"
        Visual="Material">

    <!-- Your Pages -->
    <TabBar>
        <Tab Title="Browse" Icon="tab_feed.png">
            <ShellContent ContentTemplate="{DataTemplate local:ItemsPage}" />
        </Tab>
        <Tab Title="About" Icon="tab_about.png">
            <ShellContent ContentTemplate="{DataTemplate local:AboutPage}" />
        </Tab>
        <Tab Title="Test" Icon="tab_about.png">
            <ShellContent ContentTemplate="{DataTemplate local:TestPage}" /> <!-- The relevant tab -->
        </Tab>
    </TabBar>
</Shell>

TestPage.Xaml (TestPageViewModel - это «пустой» класс, унаследованный от ReactiveObject)

<?xml version="1.0" encoding="utf-8" ?>
<rxui:ReactiveContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             xmlns:rxui="clr-namespace:ReactiveUI.XamForms;assembly=ReactiveUI.XamForms"
             xmlns:local="clr-namespace:ReactiveXam.Views"
             xmlns:vms="clr-namespace:ReactiveXam.ViewModels"
             x:TypeArguments="vms:TestPageViewModel"
             x:Class="ReactiveXam.Views.TestPage">
    <ContentPage.Content>
        <StackLayout>
            <Label Text="Welcome to Xamarin.Forms!"
                VerticalOptions="CenterAndExpand" 
                HorizontalOptions="CenterAndExpand" />
            <local:Exposure />
        </StackLayout>
    </ContentPage.Content>
</rxui:ReactiveContentPage>

Exposure.Xaml

<?xml version="1.0" encoding="UTF-8"?>
<rxui:ReactiveContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:vms="clr-namespace:ReactiveXam.ViewModels"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:TypeArguments="vms:ExposureViewModel"
             xmlns:rxui="clr-namespace:ReactiveUI.XamForms;assembly=ReactiveUI.XamForms"
             x:Class="ReactiveXam.Views.Exposure">
      <StackLayout>
        <Label x:Name="balance" />
        <Label x:Name="exposure" />
    </StackLayout>
</rxui:ReactiveContentView>

Exposure.xaml.cs

    public partial class Exposure : ReactiveContentView<ExposureViewModel>
    {
        public Exposure()
        {
            InitializeComponent();
            ViewModel = new ExposureViewModel();

// The code below slows down the loading of the tab (~5x slower).
            this.WhenActivated((disposable) =>
            {
                this.OneWayBind(ViewModel, vm => vm.Exposure, v => v.exposure.Text).DisposeWith(disposable);
                this.OneWayBind(ViewModel, vm => vm.Balance, v => v.balance.Text).DisposeWith(disposable);
            }); 

        }
    }

ExposureViewModel

    public class ExposureViewModel : ReactiveObject
    {
        double balance, exposure;

        public double Balance
        {
            get => balance = 500.00d;
            set => this.RaiseAndSetIfChanged(ref balance, value);
        }

        public double Exposure
        {
            get => exposure = 25.00d;
            set => this.RaiseAndSetIfChanged(ref exposure, value);
        }
        public ExposureViewModel()
        {
        }
    }

1 Ответ

3 голосов
/ 03 октября 2019

Ну, я уделяю много времени удивительной оболочке Xamarin Forms Shell, и я думаю, что это является причиной задержки производительности, о которой вы говорите прямо сейчас.

Когда вы читаетеВ документах Microsoft четко сказано:

В приложении Shell каждая ContentPage, являющаяся дочерним элементом объекта ShellContent, создается во время запуска приложения. Добавление дополнительных объектов ShellContent с использованием этого подхода приведет к созданию дополнительных страниц во время запуска приложения, что может привести к ухудшению качества запуска. Однако Shell также может создавать страницы по требованию в ответ на навигацию. Для получения дополнительной информации см. Эффективная загрузка страницы.

Хорошо, что вы можете исправить это, загрузив эти страницы по требованию, как вы можете видеть здесь: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/tabs#efficient-page-loading

По сути, это можно сделать с помощью разметки DataTemplateрасширение для преобразования каждого ContentPage в DataTemplate, а затем установки результата в качестве значения свойства ShellContent.ContentTemplate.

...