5 种 提高 Xamarin.Forms App 启动时间的 方法

适用于 iOSAndroidXamarin SDK 提供了一个非常高性能的基础,以便构建 Xamarin.Forms 跨平台应用程序。当你努力优化 Xamarin.Forms 应用程序的启动速度和响应速度时,请记住,能优化构建在 Xamarin SDK 基础之上的iOSAndroid应用的方法 也能优化 Xamarin 跨平台的应用程序。而且这些优化从最开始的启动就起作用。

PS: 即适用于原生 AndroidiOS 的性能优化方法也适用于 Xamarin.iOSXamarin.Android

启动时间的定义

首先,让我们将 启动 定义为从用户点击应用图标到第一个界面可见时发生的所有事情。当你对比一个 新建的Xamarin.Android 和 新建的 Xamarin.Forms 项目的时候,你会发现 Xamarin.Android 项目加载的更快一些。这中间发生了什么呢?

Xamarin.Forms 不仅提供跨平台共享的 UI, 还提供了一些常见的应用功能比如: AppLinks for deep linking, Navigation, MessagingCenter, and DependencyService, 还有一些必要的跨平台的 UI: alerts, action sheets, toolbars, status bars, etc.

如果你向 Xamarin.Android 应用程序添加类似的实现时, 你就会看到之前 Xamarin.AndroidXamarin.Forms 性能上的差异相差无几了。这就解释了为什么 Xamarin.Forms app 为什么启动时间会稍长一点,那我们如何来控制 Xamarin.Forms app 的启动时长呢? 以下是我在 iOSAndroidUWP targets 中优化 启动时间 的五个建议。

1. 优先加载本地资源

我们通常希望在 应用程序启动后 立即加载最新的数据, 但这会减慢 first screen appearingpopulating 的速度(类似:Android Actvity --> OnCreate() and OnResume()). Use state from a previous run or have content ready to go that is for the first run.

We often want to load fresh data as soon as our application has launched, but this will only slow down the first screen from appearing and populating. Use state from a previous run or have content ready to go that is for the first run.

如果你的 app 可以离线使用的话,我们很推荐这样做。优先加载本地资源,之后立即为你的第一个屏幕填充内容了。Azure Mobile Apps and Realm with Azure 是很好的选择。

当你必须 访问网络 以获取首次运行内容时,你可以提供一些 UI,比如通过使用 加载指示器 (loading indicator)告诉用户 你的 app 正在做什么。这样一来还可以避免白屏的尴尬:先展示占位符,告诉用户屏幕已经加载出来,现在要去加载数据。

Payload Tips:将你的网络的需求降到最低,不要花时间处理一些耗时的操作,比如解析字符串,而是在需要表示数据时提供数据。

2. 优化 Assets

图像和视频通常会比较大,可能会大幅减慢屏幕的初始渲染速度。减少对 Assets 的依赖,并优化您用于必要 dimensions 的任何 media 文件。不要指望 Android OS 为您调整 Assets 大小。

对于 Android target screensAssets 放置在表示其 density 的文件夹中:

  • ldpi (low) ~120dpi
  • mdpi (medium) ~160dpi
  • hdpi (high) ~240dpi
  • xhdpi (extra-high) ~320dpi
  • xxhdpi (extra-extra-high) ~480dpi
  • xxxhdpi (extra-extra-extra-high) ~640dpi

还有一个特殊的 nodpi 密度,告诉 Android 无论屏幕密度如何都不会 scale the resources 。

当您将较大的 image 放在 ldpi 文件夹中并在 xxhdpi 的屏幕上加载该资源时,Android 会对其进行扩展。
这很慢并且会使增加运行时内存的消耗,有时甚至会导致应用程序崩溃;

要管理那么多的 assetsassets 资源,非常建议使用像 SketchZeplin 一样的应用来生成适用于多种尺寸屏幕的 资源文件。

Xamarin.Android 7.0 中还出了个实验性的选项 pre-crunch PNG 文件:AndroidExplicitCrunch.

这进一步减少了 Assets(和应用程序)的大小,减少了 build time 并对运行时的运行速度也有一定的优化。想要使用这个功能,需要编辑你的 Android csproj 文件,并修改 build configuration 中的 PropertyGroup.

<PropertyGroup>
    ...
    <AndroidExplicitCrunch>true</AndroidExplicitCrunch>
</PropertyGroup>

3. 懒加载你不需要的东西 来进行优化

App.xaml Resources 可以放置 styles, fonts 或者其它一些你需要在你的 app 中使用的 资源,但这些都是在启动时加载的。所以如果你想 毫秒 级别的减少你的 app 启动时间的话, 那你就去掉 App.xaml 中的这些代码,lazy load it by page or in another method.

4. Enable XAML Compilation

XAML 是一种流行且功能强大的声明用户界面的方式。如果你选择使用 C# 并用 XAML 来构建 UI 的话....

XAML is a popular and expressively powerful way to declare your user interface. If you opt to stay in C# and build your UI there, it’s naturally compiled along with the rest of your code, giving you compile-time checking and speed. When you want that same benefit while using XAML, you enable XAML Compilation (XAMLC). This will compile your XAML into Intermediate Language (IL) and add it to your compiled assembly, resulting in faster startup and runtime performance.

我们来看看如何启用它:

application 级别,您可以声明您的 XAMLC 选项,它将影响您的整个应用程序:

using Xamarin.Forms.Xaml;
...
[assembly: XamlCompilation (XamlCompilationOptions.Compile)]
namespace PhotoApp
{
    ...
}

如果要在 class 级别设置 XAMLC 选项,则可以:

using Xamarin.Forms.Xaml;
...
[XamlCompilation (XamlCompilationOptions.Compile)]
public class HomePage : ContentPage
{
    ...
}

启用 XAMLC 后,您将获得大多数所有属性的编译时 XAML 检查,UI 将更快地呈现。当您在程序集中交换 IL.xaml 文件大小时,文件大小可能保持不变或略有增长。

When XAMLC is enabled you’ll get compile time XAML checking on most all properties and UI will render faster. File size may remain unchanged or grow slightly as you are trading .xaml file size for IL in the assembly.

5. 减少 Assemblies 的数量

通常情况下便利总是要付出成本的。这可能是一个非常小的成本,但你想全力优化性能时就另说了。通过 NuGet 来引用第三方库虽然简单好用,但实际情况是,当调用跨越 boundaries时,移动应用程序所依赖的组件越多(越大)自然会降低执行速度。

Convenience comes at a cost, as usual. It might be a very small cost, but you want to leave no stone unturned when tuning for performance. While NuGet packages are awesome for leveraging other libraries, the reality is that the more (and larger) assemblies your mobile application depends on naturally slows down the execution as calls pass across boundaries.

Xamarin.Forms, for example, inspects all assemblies for [ExportRenderer] attributes and currently has no method to opt-in or opt-out. This is something we’re working to improve.

权衡每个依赖的优缺点,并在可能的情况下将该代码放入你的主应用程序中。这有可能会让你的工作量变大一些,所以你权衡一下吧。这是经常被忽略的一点,但也是可以用来优化 app 性能的一点。

彩蛋 1:预编译 AOT -- Ahead of Time Compilation

之所以叫它彩蛋是因为我们目前还是把 Android 中的 AOT 当作 experimental 的功能来看,而且这不是对所有人都适用。 当然,iOS 里默认使用 AOTLLVM 编译,所以在这也没什么好说的。

Enable the experimental Android AOT and get immediate improvement in startup as well as overall speed by reducing some Just-In-Time compilation overhead. The price paid is an increase in the size of your APK, so you should try this out and weigh the pros and cons for your application. To enable AOT, open your project configuration and check the box.

VS for Mac 中 开启这个选项:

Android_Build_Settings_General_Callout.png

注意: AOT is available on Xamarin Android 5.1 and 7.0+

彩蛋 2:优化 编译时间 | Build Time Improvements

Xamarin 项目通常比原生的项目会花费更多的 build time, 如何来优化呢?可以参考:关于如何加快编译 Xamarin 应用程序所需时间的提示和技巧

While not directly applicable to startup improvement, one of our awesome mobile solutions architects Brandon Minnick has shared his collection of build optimization configurations. Check it out on GitHub.

之后怎么优化?

以上只是我比较喜欢的几个建议,而且它们不仅可以优化 app 启动时间。 我可以继续关于 扁平化布局,优化布局周期中的 measuringlayout 等来继续深入优化。你可以在 Xamarin.Forms Performance guide 里看到这些内容。

社区 和 Xamarin.Forms 工程师团队一直在 Xamarin Forums (论坛) 讨论一些 Xamarin 的痛点和相应的解决方案。 欢迎大家来加入一起讨论下如何继续优化 Xamarin 的性能。

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容