8

我们正在 PCL 上开发跨平台应用程序,但目前我们仅使用 android 设备进行测试。
我们担心的是启动应用程序需要大约 6 到 8 秒(取决于我们测试的设备),这非常慢。
放置几个断点后,我们看到时间消耗相当均匀。
我们确实注意到这个特定部分花费了更长的时间:

  • 在 MainActivity 上到达 onCreate() 之前 1 秒(有一个启动屏幕,之前只有一个图像和背景颜色)
  • 1 秒开启base.OnCreate(bundle);
  • 1 秒开启global::Xamarin.Forms.Forms.Init(this, bundle);
  • 1.5s on Page mainPage = new LogScreen();(创建主页然后将其设置为主导航页)。
4

4 回答 4

8

我建议的第一件事是不要对您的应用程序的调试版本进行基准测试,Mono 运行时和 Jit'd 代码的代码路径与发布版本、共享运行时的使用、程序集大小等不同,等等,等都会影响启动和执行时间。

以下是使用内部基准测试器(有条件地编译、未注入并使用操作系统的系统时钟)在高端和低端设备上积极调整的基于 Android Forms 的应用程序的启动时间示例。

应用概述:

  • Xamarin.Forms v2.4.0.269-pre2
  • 混合编码和基于 XAML 的页面、控件等...
  • XAML 编译器已启用
  • “启动画面”已禁用
    • 基于主题的启动画面MainActivity将添加:
      • 在快速设备上启动时间超过 200 毫秒,
      • 在具有慢速闪存访问的设备上 1-2 秒
    • 只是不要使用基于 Activity 的闪屏 ;-)
  • 多索引
  • Proguard'd(通过带有自动反馈循环的 UI 测试积极减少 jars)
  • 链接器(链接全部,通过带有自动反馈的 UI 测试生成的自定义链接描述文件,大大减少了程序集的大小)
  • 100% 源代码构建,允许折叠命名空间和减少程序集
  • 没有第 3 方 DI/IoC 的 Viper 架构
  • 使用数据、资源广告网络优先级队列的延迟加载设计
  • 用于所有数据的领域实时对象和查询(DB 最小大小:250MB,最大大小 1.2GB)

时间是通过一个 shell 脚本生成的,该脚本重启设备,监控启动以等待系统稳定,启动一系列应用程序(GApps、Facebook、Instagram、Twitter 等),等待系统稳定,然后通过以下方式启动 Forms 应用程序:

export deviceTime=$(echo "$(adb -s $deviceID shell cat /proc/uptime | awk '{print $1}') * 1000" | bc -l)
adb -s $deviceID shell am start -n com.sushihangover.GeneticCancerDNAMapper/com.sushihangover.GeneticCancerDNAMapper.DevOpsDashboard --el startTime ${deviceTime%.*}

Google Pixel(基于奥利奥)设备(应用程序可在约 430 毫秒内使用):

I GeneticCancerDNAMapper: 0.162 : Xamarin.Forms.Platform.Android.FormsAppCompatActivity.OnCreate
I GeneticCancerDNAMapper: 0.164 : Xamarin.Forms.Platform.Android.FormsAppCompatActivity.base.SetTheme
I GeneticCancerDNAMapper: 0.201 : Xamarin.Forms.Platform.Android.FormsAppCompatActivity.base.OnCreate
I GeneticCancerDNAMapper: 0.244 : Xamarin.Forms.Forms.Init
I GeneticCancerDNAMapper: 0.266 : Realms.Realm.GetInstanceAsync ~Get Instance & Data~
I GeneticCancerDNAMapper: 0.324 : Realms.Realm.GetInstanceAsync ~Obtained Instance & Data~
I GeneticCancerDNAMapper: 0.324 : Xamarin.Forms.Application Content
I GeneticCancerDNAMapper: 0.349 : Xamarin.Forms.Application Content ~Creation Completed~
I GeneticCancerDNAMapper: 0.353 : Xamarin.Forms.Application.MainPage ~Displayed~
I GeneticCancerDNAMapper: 0.43 : Xamarin.Forms.Platform.Android.FormsAppCompatActivity.LoadApplication

低端“Android One”512MB 设备,带非常慢的闪存(应用程序可在约 4.5 秒内使用):

回复:https ://en.wikipedia.org/wiki/Android_One

I/GeneticCancerDNAMapper(10904): 2.453 : Xamarin.Forms.Platform.Android.FormsAppCompatActivity.OnCreate
I/GeneticCancerDNAMapper(10904): 2.467 : Xamarin.Forms.Platform.Android.FormsAppCompatActivity.base.SetTheme
I/GeneticCancerDNAMapper(10904): 2.731 : Xamarin.Forms.Platform.Android.FormsAppCompatActivity.base.OnCreate
I/GeneticCancerDNAMapper(10904): 3.016 : Xamarin.Forms.Forms.Init
I/GeneticCancerDNAMapper(10904): 3.166 : Realms.Realm.GetInstanceAsync ~Get Instance & Data~
I/GeneticCancerDNAMapper(10904): 3.571 : Realms.Realm.GetInstanceAsync ~Obtained Instance & Data~
I/GeneticCancerDNAMapper(10904): 3.571 : Xamarin.Forms.Application Content
I/GeneticCancerDNAMapper(10904): 3.772 : Xamarin.Forms.Application Content ~Creation Completed~
I/GeneticCancerDNAMapper(10904): 3.799 : Xamarin.Forms.Application.MainPage ~Displayed~
I/GeneticCancerDNAMapper(10904): 4.457 : Xamarin.Forms.Platform.Android.FormsAppCompatActivity.LoadApplication
于 2017-09-12T00:32:28.013 回答
5

这是使用 Xamarin.Forms 时的常见问题,有很多与此相关的线程,特别是这个:

https://forums.xamarin.com/discussion/93178/lets-talk-performance/p6

好消息是 Xamarin 团队正在努力。

以下是一些您可以改进的提示:

https://blog.xamarin.com/5-ways-boost-xamarin-forms-app-startup-time/

于 2017-09-11T20:32:50.283 回答
4

我会将我们为此找到的所有解决方案汇总在一起,以便将其全部集中在一个地方。

其中一个答案链接了这篇文章,这非常有用。

除此之外,我们还做了以下事情:

  • 在所有项目的属性中选中“优化代码”框。不确定这是否会专门改善启动时间,但它似乎对整体性能有所帮助。
  • 添加AOT 和 LLVM。我们找到了一种方法来做到这一点,即使该选项在我们的 IDE 上不可用。这会大大增加构建时间,所以如果你想这样做,我建议只在发布版本时这样做。
  • 启用Xamarin 快速渲染。这是一个实验性的东西,所以你应该阅读一些关于它的文档,但它是通过global::Xamarin.Forms.Forms.SetFlags("FastRenderers_Experimental");MainActivity.OnCreate()方法上添加这一行来完成的,之前global::Xamarin.Forms.Forms.Init(this, bundle);
  • 更新我们的 Xamarin.Forms Nuget版本。这需要在您的解决方案的所有项目中使用相同的版本,我们在点击手势方面遇到了一些问题,这也得到了改进。
  • 链接 SDK 程序集。在“链接”下的“属性”>“Android 选项”上,您可以设置为链接“仅 SDK 程序集”。您也可以设置为所有程序集,但如果您使用自定义程序集,则不建议这样做。
  • 预加载屏幕。这大大提高了应用程序本身的性能,我们所做的是在每个屏幕、背景、视图和视图模型上加载接下来需要的地方,因此当将它们推送到导航堆栈时,它们已经加载了。这大大减少了页面之间的转换时间。
于 2018-07-03T15:11:02.797 回答
0

我找到了解决方案。例如,我们有 5 个选项卡。我们有 5 个视图模型或 5 个代码隐藏。我们定义的每个选项卡视图模型构造函数都定义了启动计时器方法。并且第一个选项卡构造函数在计时器启动后初始化 700 毫秒。第二个选项卡在 1 秒后开始。让我们为此编写代码:

第一个选项卡 Home 和 home viewmodel 是 HomeViewModel。

public void HomeTimer()
{
    timer.Interval = 700;

    timer.Elapsed += (sender, e) => OnTimedEvent(sender, e);

    timer.AutoReset = false;

    timer.Enabled = true;
}

private void OnTimedEvent(object sender, ElapsedEventArgs e)
{
    timer.Enabled = false;

    Yap(); // yap command all the page listview and get api.
}
System.Timers.Timer timer = new System.Timers.Timer();

public HomeViewModel()
{
    HomeTimer(); // hometimer starting
}

第二个选项卡是 MyPage 和 viewmodel 是 MyPageViewModel 和构造函数是相同的:

public void MyPageTimer()
{
    timer.Interval = 1000; //look. home page starting 0.7 seconds after and mypage starting 1 seconds after.

    timer.Elapsed += (sender, e) => OnTimedEvent(sender, e);

    timer.AutoReset = false;

    timer.Enabled = true;
}

private void OnTimedEvent(object sender, ElapsedEventArgs e)
{
    timer.Enabled = false;

    GetMypage(); // and getmypage method all the initialize the page and listview and webapi works.
}
System.Timers.Timer timer = new System.Timers.Timer();

public MyPageViewModel()
{
    MyPageTimer();
}

这个操作我从启动开始删除 1 秒。在此操作之前,我的应用程序开始 3.2 秒,现在开始 2.2 秒。

于 2019-06-15T17:29:28.040 回答