优化应用或页面加载以获取更高的性能

影响用户对应用看法的关键因素之一是应用打开和发挥作用的速度。 因此,优先考虑此目标对于生成高性能应用至关重要。 为了实现更好的应用性能,需要注意三个主要领域:

  1. 快速加载数据
  2. 高效计算
  3. 最大限度地减少所需资源

其中每个领域都有几个常见的反模式。

快速加载数据

遵循这些指南来实现快速数据加载应用。

避免直接使用大量数据填充集合

有时,作者使用 ClearCollect() 将数据从服务器复制到应用中的集合。 此做法是源中委派限制的解决方法,或者因为他们计划将应用中的集合用于其他目的。 当稍后利用集合时,使用 ClearCollect() 可能会提高应用的速度。 但是,在实施时请务必谨慎操作。 通过此方式使用 ClearCollect 可能会导致应用加载时间变慢或在页面之间导航时变慢。 必须先完成 ClearCollect(),然后才能看到库或表中的数据。 如果有大量数据或者您将此方法用于过多数据源,此步骤可能需要很长时间。 集合最适合数据较小并且需要对集合进行大量计算的情况。 例如,在线订单篮就是集合的一种典型用法。 在选择提交订单之前,客户可能会多次更新和删除物料。 此外,您可以使用更多数据项(例如潜在折扣、亮点等)来扩充集合。“只读”数据应以本机方式访问 - 无需将其引入集合中。

考虑避免调用 Power Automate 来填充集合

此问题与上一节略有不同。 有时,作者也会在 Power Apps 中使用 Power Automate 来填充他们的集合。 实例化 Power Automate 大约需要 0.6 秒的性能成本。 Power Automate 在每次调用时都必须独立启动。 它必须分配内存,放置正确的组件并准备好运行。 就像上述的建议一样,对 Power Automate 的一次或两次调用可能不是问题,具体取决于您的应用。 但是,几乎普遍来说,性能较差的应用过度使用了此方法。 性能成本会迅速增加并破坏应用的性能。

避免使用 SaveData() 和 LoadData() 作为完全离线场景

一些作者使用 ClearCollect(),然后使用 SaveData() 来存储数据以供通用离线使用。 您可以使用 SaveData() 将集合保存到您的设备,然后使用 LoadData() 在您处于离线状态时加载它。 但是,对于具有大量数据或数据复杂的情况,不建议使用此方法。 它会使您的应用变慢,因为它必须等待 ClearCollect() 完成才能显示数据。 对于小型且简单的数据场景(例如首选项和简短列表),您应该仅使用 SaveData() 和 LoadData()。 处理大量离线数据的更好方法是使用适用于 Dataverse 的 Power Apps 离线功能。 此功能可以更有效地处理更大、更复杂的数据。

使用显式列选择

默认情况下,显式列选择处于打开状态。 但是,一些作者会关闭此功能。 问题是,在打开显式列选择 (ECS) 的情况下,如果首先将数据检索到集合中,有时不会从数据源检索列。 由于某些表可能有许多列,因此 ECS 会根据控件(例如库和窗体)中的使用情况自动计算需要检索哪些列。由于某些表可以有许多列,因此减少下载的大小可以提高性能。 某些表可以有一百个列或更多。 如果您的应用只需要使用 10 个列,并且您从 100 个列的表中取出所有列,则您取出的数据量是实际需要的十倍。

当将数据纳入集合中时会出现大多数问题。 如果在控件中显式引用列,则 ECS 很有效。 而且,ECS 通常适用于集合。 但是,当数据在集合和变量中移动时,列世系有时会丢失。 而且,Power Apps 可能会丢失它应该检索的列的跟踪。 若要解决此问题,您可以使用 ShowColumns 函数强制 Power Apps“记住”该列。 例如:

    ClearCollect(
        MyColTable, 
        ShowColumns(Filter(BankAccounts, AcountNo = 32),
        "Col1", 
        "Col2", 
        "Col3")
    );

其中 Col1Col2Col3 是您希望从数据源(例如,Account 数据源)检索的列。

或者,您可以将隐藏的控件添加到引用该列的窗体。 这会强制 Power Apps“记住”该列。

快速计算

快速(或高效)计算本身就是一个性能目标。 有关详细信息,请参阅快速(高效)计算。 但是,有一些常见的反模式也会影响应用加载,因此我们在这里讨论它们。 下面是您应该考虑的可能影响应用启动或页面导航的优化列表。

使用 App.Formulas

历史上许多作者都将大量计算放在 OnStart 中。 当您在 OnStart 中放置表达式时,它会强制 Power Apps 在应用启动时且在其他所有操作之前精确运行该表达式。 但是,通过引入 App.Formulas,您可以让 Power Apps 决定何时运行表达式。 Power Apps 可以在需要之前运行“实时”公式。 有关详细信息,请参阅应用公式。 使用 App.Formulas 将您的公式拆分为 Power Apps 可以更有效地安排执行的部分。

使用并发

使用并发函数以允许同时执行公式。 通常使用此函数来填充集合,因为它允许并行执行。 虽然这可以提供一定程度的加速,但添加许多数据源可能会导致计时和限制问题。

针对隐藏控件使用增强的性能

在自 2022 年 12 月以来创建的所有新应用中默认启用时,Power Apps 不会呈现任何最初不可见的控件。

最大限度地减少所需资源

最大限度地减少启动应用或屏幕所需的资源。 这项工作包括仔细确定应用或屏幕所需资源的范围或进行分区。 下面是几种可以帮助您的方法。

使用低依赖项启动屏幕并消除未使用的屏幕。

使用低依赖项的第一个屏幕,例如应用程序的欢迎屏幕。 创建一个不加载图库、表或参考数据的屏幕。 这可以管理用户对速度的感知,并允许 Power Fx 适当地将一些计算延迟到以后。 如果您有任何未使用的屏幕,请将其删除。

使屏幕之间的跨屏幕依赖项保持较低

跨页面引用强制通过引用加载其他页面,例如引用页面上的控件并放入集合中。 有些引用可能不可避免。 如果可能,将公共引用集中到单个页面,以便仅加载页面。

考虑嵌入的媒体

作者有时会在他们的应用中嵌入媒体以确保快速加载。 如果您已嵌入媒体,请考虑您是否正在使用它。 如果未在使用,请删除它。 如果您已嵌入 .png 文件,请考虑替换较小的 .svg 文件。 请注意,如果您使用 .svg,.svg 的字体必须位于客户端计算机上。 考虑嵌入的媒体分辨率。 对于将要使用的设备来说它是否太高了?

不要忘记 App.StartScreen

如果您使用 App.StartScreen,请确保第一个屏幕是空白屏幕。 由于应用的当前打包,第一个逻辑屏幕始终与应用初始化逻辑捆绑在一起,并将进行初始化,无论我们是否导航到它。

考虑拆分应用

如果您的应用较大,请考虑将其分区为较小的应用。 如果功能在应用的不同部分中足够独立,则此方法可能有效。 在这种情况下,您创建一个实际的单独应用,使用包含来自第一个应用或父应用的上下文的参数启动该应用。

建议

为了实现快速应用和页面启动的目标,请考虑以下问题和建议:

  1. 是否在第一个屏幕中加载大量数据? 是否可以使用不同的第一个屏幕?
  2. 是否在应用加载开始时运行许多命令或 Power Fx 表达式? 是否可以将这些命令和表达式推迟到应用程序的稍后某个时间点? 仅获取启动应用时实际所需的数据? 1 是否可以使用 App.Formulas 将 App.OnStart 中的表达式转换为命名公式? 这允许 Power Fx 决定何时实际执行公式,而不是强制它在加载或导航事件时发生。
  3. 是否可以使用单独的 Power Automate 流在本地数据存储中创建临时表,例如合并不同来源的数据的 Dataverse? 然后在 Power App 中访问该数据?
  4. 对于业务流程启动,是否可以使用服务器触发的操作,而不是调用 Power Automate 流?
  5. 是否可以在服务器上创建一个视图来为您连接数据?
  6. 如果您想要在应用中使用离线数据,是否可以使用适用于 Dataverse 的 Power Apps 离线功能? 如果您的数据不在 Dataverse 中,是否可以将其移动到该位置?