- PVSM.RU - https://www.pvsm.ru -
Друзья! Мы продолжаем колонку на тему разработки мобильных приложений на Xamarin. И
после небольшого перерыва готовы вернуться к рассмотрению особенностей использования Xamarin.Forms при разработке бизнес-приложений для iOS и Android. Все статьи из колонки можно будет найти и прочитать по ссылке #xamarincolumn [1]
В сегодняшней статье мы рассмотрим вопросы производительности приложений и оптимизации самого процесса разработки.
В замечательной сказке про Винни-Пуха пчелы делились на правильных и неправильных. Аналогично и окружения, в которых будет идти разработка приложений могут быть условно разделены на правильные и неправильные.
Начнем мы с компьютеров, на которых будет идти разработка.
В своей практике в качестве основной среды мы используем Windows 10 и Visual Studio 2015, поэтому столкнулись с тем, что сборка приложений (в первую очередь Android) занимает непозволительно долго времени.
Мы стали выяснять в чем здесь дело и выявили несколько узких мест, замедляющих разработку:
Особо продвинутым можно рекомендовать использование ОЗУ в качестве раздела для хранения проектов и системной Temp-папки — для этого нужно использовать одну из программ класса RAM Disk [2].Точных измерений при использовании SSD+RAM Disk не производили, но на глаз разница колоссальна.
Итак, считаем, что с правильным окружением мы разобрались.
Одним из важных механизмов Xamarin.Forms является возможность использования XAML (на базе XML) для описания интерфейса пользователей.
На наш взгляд, это является хорошим решением с точки зрения технологии производства, так как происходит отделение логики от описания интерфейса и сама по себе UI-разработка становится очень похожей на HTML-верстку, даже стили контролов можно задавать в одном месте как с CSS (ликбез по стилям по ссылке [3]), включая небольшой тюнинг для разных платформ (Device.OnPlatform).
Все было бы отлично, если бы не одно большое “НО”, которое характерно для Xamarin.Forms версии 1.х — XAML-файлы интерпретировались на лету, включая создание всех необходимых контролов и их размещение на экране. Из-за этого каждое открытие нового окна со сложной компоновкой происходило дольше, чем хотелось бы.
В версии 2.0 этот недостаток устранили, реализовав предварительную компиляцию XAML. Использовать ее можно как для отдельных страниц и View на XAML, так и для всего проекта целиком.
Включаем компиляцию отдельной XAML-страницы (файл MainPage.xaml.cs, например)
using Xamarin.Forms.Xaml;
...
[XamlCompilation (XamlCompilationOptions.Compile)]
public class MainPage : ContentPage
{
...
}
Активируем компиляцию по всему проекту — добавляем новую строку в конец файла Properties/AssemblyInfo.cs в PCL-проекте:
...
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
Однако в некоторых случаях, особенно при реализации ячеек для ListView, может быть эффективнее описать компоновку для ViewCell/View/Page руками в коде на C# или спуститься на уровень iOS/Android [4].
Но к ListView мы еще вернемся.
Первое, с чем сталкиваются начинающие разработчики на Xamarin.Forms — залипания при прокрутке в списках на базе ListView. Чего греха таить, это одно из болезненных мест платформы, отбрасывающее тень на весь остальной функционал, так как списки используются в больших количествах и практически во всех приложениях.
Для начала мы рассмотрим работу с изображениями, так как очень часто это является одной из причин залипаний.
Стандартный компонент для отображения Image хорош, даже поддерживает кеширование, но он мало пригоден при использовании в реальных проектах. Когда год назад мы уперлись в ограничения Image, пришлось сделать свой простенький кешер изображений с автоматическим масштабированием — для отображения в ячейку передавалась уменьшенная версия, так как с большими изображениями списки просто умирали (это не проблема Xamarin.Forms, а вообще любой разработки приложений, но на Xamarin.Forms она была очень острой).
Потом мы перепробовали несколько различных библиотек и в конце концов остановились на превосходном компоненте под названием FFImageLoading [5].
Он доступен в Nuget () и позволяет решить сразу несколько задач:
Вот так использовать компонент при разработке на XAML:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Sample.Pages.MainPage"
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
Title="FFImageLoading Demo">
<ContentPage.Content>
<ffimageloading:CachedImage HorizontalOptions="Center" VerticalOptions="Center"
WidthRequest="300" HeightRequest="300"
DownsampleToViewSize="true"
Source = "https://unsplash.it/600/600/?random"
LoadingPlaceholder = "placeholder.png">
</ffimageloading:CachedImage>
</ContentPage.Content>
</ContentPage>
Вот так можно еще немного улучшить работу FFImageLoading (класс AppDelegate.cs для iOS и MainActivity.cs для Android):
var config = new Configuration
{
HttpClient = new HttpClient(new ModernHttpClient.NativeMessageHandler()), //используем быстрые библиотеки для загрузки
FadeAnimationDuration = 250, //ускоряем анимацию появления
};
FFImageLoading.ImageService.Instance.Initialize(config);
С помощью FFImageLoading мы оптимизировали отображение изображений в списках и теперь можем перейти к следующему шагу.
Первая рекомендация касается механизмов работы ListView. В ранних версиях Xamarin.Forms не поддерживался механизм повторного использования созданных ячеек, что приводило к созданию экземпляров ViewCell каждый раз при необходимости их отображения — это и было первой серьезной причиной залипаний при скроле.
В последних версиях Xamarin.Forms реализован механизм повторного использования созданных ячеек и для его активации необходимо задать свойству CachingStrategy значение ListViewCachingStrategy.RecycleElement.
Реализация в XAML:
<ListView CachingStrategy="RecycleElement">
...
</ListView>
Реализация на C#:
var listView = new ListView(ListViewCachingStrategy.RecycleElement);
После этого созданные экземпляры ViewCell начинают использоваться повторно и к ним просто подключаются (через Binding) необходимые модели данных по мере отображения.
Еще один интересный способ подсказал мой коллега Кирилл — просто останавливать загрузку и отображение картинок во время прокрутки списка. Этот способ также рекомендуют использовать и создатели FFImageLoading.
Для этого необходимо сделать свой рендерер для ListView для каждой платформы и переопределить события прокрутки.
Пример для Android:
_listView.ScrollStateChanged += (object sender, ScrollStateChangedEventArgs scrollArgs) => {
switch (scrollArgs.ScrollState)
{
case ScrollState.Fling:
ImageService.Instance.SetPauseWork(true); // ставим загрузку картинок на паузу
break;
case ScrollState.Idle:
ImageService.Instance.SetPauseWork(false); // возобновляем загрузку картинок
// здесь должен быть ваш код отображения изображений в отображаемых ячейках
ShowMyImage();
break;</p>
}
};
При необходимости вы также можете создать свои реализации ViewCell через механизм Custom Renderer [6] для каждой платформы — такой подход может быть актуален для сложных ячеек с большим количеством встроенных контролов.
Также хорошие результаты при работе с большими объемами данных и сложными ячейками позволяет достичь использование нативных компонентов UICollectionView (для iOS [7]) и RecyclerView (для Android [8]), но это решение можно рекомендовать продвинутым разработчикам.
Пример использования данных классов представлен в библиотеке TwinTechs [9] — обязательно к знакомству, так как там есть видео-ролики с результатами оптимизации.
Итак, на первых порах освоения Xamarin.Forms необходимо уделить особое внимание работе со списками и подходам к повышению производительности [10]. Это позволит не отвлекаться на данные особенности в последующей разработке.
В нашей сегодняшней статье мы рассмотрели базовые механизмы оптимизации рабочего окружения и первые шаги к разработке бизнес-приложений на базе Xamarin.Forms.
В следующем материале мы расскажем об использовании иконочных шрифтов в стиле Font Awesome, инструмента Fody для сокращения кода у ViewModel и механизмах ручной отрисовки своих интерфейсных элементов с помощью библиотеки NControlView.
Оставайтесь на связи и добавляйте свои комментарии и вопросы!
Вячеслав Черников — руководитель отдела разработки компании Binwell [11]. В прошлом — один из Nokia Champion и Qt Certified Specialist, в настоящее время — специалист по платформам Xamarin и Azure. В сферу mobile пришел в 2005 году, с 2008 года занимается разработкой мобильных приложений: начинал с Symbian, Maemo, Meego, Windows Mobile, потом перешел на iOS, Android и Windows Phone.
Автор: Microsoft
Источник [16]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/ios/138565
Ссылки в тексте:
[1] #xamarincolumn: https://habrahabr.ru/search/?target_type=posts&q=%5Bxamarincolumn%5D&order_by=date
[2] RAM Disk: https://www.bing.com/search?q=RAM+Disk
[3] по ссылке: https://blog.xamarin.com/easy-app-theming-with-xamarin-forms-styles/
[4] на уровень iOS/Android: https://developer.xamarin.com/guides/xamarin-forms/custom-renderer/viewcell/
[5] FFImageLoading: https://github.com/luberda-molinet/FFImageLoading
[6] Custom Renderer: https://developer.xamarin.com/guides/xamarin-forms/custom-renderer
[7] iOS: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UICollectionView_class/
[8] Android: https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html
[9] TwinTechs: https://github.com/twintechs/TwinTechsFormsLib
[10] подходам к повышению производительности: https://developer.xamarin.com/guides/xamarin-forms/deployment,_testing,_and_metrics/performance/
[11] Binwell: http://www.binwell.com/
[12] по ссылке: https://habrahabr.ru/company/microsoft/blog/281142/
[13] бесплатные предложения для разработчиков: https://www.visualstudio.com/ru-ru/products/free-developer-offers-vs.aspx
[14] Visual Studio Dev Essentials: https://www.visualstudio.com/ru-ru/products/visual-studio-dev-essentials-vs.aspx
[15] Лабораторные работы: https://msdn.microsoft.com/ru-ru/mt627843.aspx
[16] Источник: https://habrahabr.ru/post/303630/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.