[iOS] Fix LayoutCompression Performance Issues #3475 (#7201)

* fix #3475

* fix blank lines in project file

* fix issue in gallery to target iOS only

* fixed white spaces in project file (thx r#)
This commit is contained in:
Giampaolo Gabba 2019-08-21 16:57:40 +02:00 коммит произвёл E.Z. Hart
Родитель ff66c5753b
Коммит e9eb9fe560
3 изменённых файлов: 157 добавлений и 3 удалений

Просмотреть файл

@ -0,0 +1,151 @@
using System;
using System.Diagnostics;
using System.Linq;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
#if UITEST
using NUnit.Framework;
using Xamarin.UITest;
#endif
namespace Xamarin.Forms.Controls.Issues
{
#if UITEST
[NUnit.Framework.Category(Core.UITests.UITestCategories.Layout)]
#endif
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 3475, "[iOS] LayoutCompression Performance Issues", PlatformAffected.iOS)]
public class Issue3475 : TestContentPage
{
string _withoutCompressionBtnId = "button1";
string _withCompressionBtnId = "button2";
string _titleLabelId = "Label1";
public static string BackButtonId = "back";
public static int ItemsCount = 150;
public static string ElapsedLabelId = "elapsed";
public static string DoneLabelId = "done";
protected override void Init()
{
var withoutCompressionBtn = new Button
{
Text = "Without Layout Compression",
Command = new Command(async () => await Navigation.PushAsync(new CompressionPage())),
AutomationId = _withoutCompressionBtnId
};
var withCompressionBtn = new Button
{
Text = "With Layout Compression",
Command = new Command(async () => await Navigation.PushAsync(new CompressionPage(true))),
AutomationId = _withCompressionBtnId
};
Content = new StackLayout
{
Padding = 10,
Children =
{
new Label
{
Text = "Tap buttons to test LayoutCompression Performance in iOS. It should be faster (or at least equal) with LayoutCompression enabled",
AutomationId = _titleLabelId
},
withoutCompressionBtn,
withCompressionBtn
}
};
}
#if UITEST
[Test]
public void Issue3475TestsLayoutCompressionPerformance()
{
RunningApp.WaitForElement(_titleLabelId);
RunningApp.WaitForElement(_withoutCompressionBtnId);
RunningApp.WaitForElement(_withCompressionBtnId);
RunningApp.Tap(_withoutCompressionBtnId);
RunningApp.WaitForElement(DoneLabelId);
RunningApp.Screenshot("Without Layout Compression");
int elapsedWithoutCompression = GetMs(RunningApp.Query(ElapsedLabelId).First().Text);
RunningApp.Tap(BackButtonId);
RunningApp.WaitForElement(_withCompressionBtnId);
RunningApp.Tap(_withCompressionBtnId);
RunningApp.WaitForElement(DoneLabelId);
RunningApp.Screenshot("With Layout Compression");
int elapsedWithCompression = GetMs(RunningApp.Query(ElapsedLabelId).First().Text);
var delta = elapsedWithCompression - elapsedWithoutCompression;
//if layoutcompressions is slower than 100 then there is a problem.
//it should be at least very similar and no more than 100ms slower i guess...
Assert.LessOrEqual(delta, 100);
}
public int GetMs(string text)
{
text = text.Replace($"Showing {ItemsCount} items took: ", "").Replace(" ms", "");
return int.TryParse(text, out int elapsed) ? elapsed : 0;
}
#endif
}
public class CompressionPage : ContentPage
{
readonly Stopwatch _sw = new Stopwatch();
readonly Label _summaryLabel;
readonly StackLayout _scrollStack;
public CompressionPage(bool shouldUseLayoutCompression = false)
{
_summaryLabel = new Label { HorizontalOptions = LayoutOptions.Center, BackgroundColor = Color.Silver, AutomationId = Issue3475.ElapsedLabelId};
var backButton = new Button { AutomationId = Issue3475.BackButtonId, Text ="Back", Command = new Command(() => Navigation.PopAsync()) };
_scrollStack = new StackLayout();
var scrollView = new ScrollView
{
Content = _scrollStack
};
var mainStack = new StackLayout { Children =
{
_summaryLabel,
scrollView,
backButton
} };
for (int i = 0; i < Issue3475.ItemsCount; i++)
{
var childLayout = new StackLayout();
if (shouldUseLayoutCompression)
{
Xamarin.Forms.CompressedLayout.SetIsHeadless(childLayout, true);
}
var label = new Label { Text = $"Item {i}" };
childLayout.Children.Add(label);
_scrollStack.Children.Add(childLayout);
}
_sw.Start();
Content = mainStack;
}
protected override void OnAppearing()
{
base.OnAppearing();
_sw.Stop();
_summaryLabel.Text = $"Showing {Issue3475.ItemsCount} items took: {_sw.ElapsedMilliseconds} ms";
_scrollStack.Children.Insert(0, new Label{Text = "Done", HorizontalOptions = LayoutOptions.Center, AutomationId = Issue3475.DoneLabelId});
}
}
}

Просмотреть файл

@ -13,6 +13,7 @@
<Compile Include="$(MSBuildThisFileDirectory)CollectionViewHeaderFooterTemplate.cs" />
<Compile Include="$(MSBuildThisFileDirectory)CollectionViewHeaderFooterView.cs" />
<Compile Include="$(MSBuildThisFileDirectory)CollectionViewItemsUpdatingScrollMode.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue3475.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue6945.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue5046.xaml.cs">
<DependentUpon>Issue5046.xaml</DependentUpon>

Просмотреть файл

@ -20,13 +20,15 @@ namespace Xamarin.Forms.Platform.MacOS
{
}
VisualElementPackager(IVisualElementRenderer renderer, VisualElement element)
VisualElementPackager(IVisualElementRenderer renderer, VisualElement element, bool isHeadless = false)
{
if (renderer == null)
throw new ArgumentNullException(nameof(renderer));
Renderer = renderer;
renderer.ElementChanged += OnRendererElementChanged;
if (!isHeadless)
renderer.ElementChanged += OnRendererElementChanged;
SetElement(null, element ?? renderer.Element);
}
@ -88,7 +90,7 @@ namespace Xamarin.Forms.Platform.MacOS
Performance.Start(out string reference);
if (CompressedLayout.GetIsHeadless(view))
{
var packager = new VisualElementPackager(Renderer, view);
var packager = new VisualElementPackager(Renderer, view, isHeadless:true);
view.IsPlatformEnabled = true;
packager.Load();
}