数据加载策略

已完成

Power Apps 为用户提供有效的业务数据和流程处理方式。 应用可以使用连接器访问数据。 应用启动或显示新屏幕时,通常检索某些信息以便进行初始显示。 屏幕上的控件通常直接绑定连接器并且在为用户呈现屏幕时检索数据。 在屏幕间导航也会再次检索数据。 在某些情况下,如未进行优化,本流程可能导致用户体验低于标准或进行多余的处理。 您可以通过评估用户的需求和数据加载方式制定策略提高性能。

评估应用时应考虑以下关键问题:

  • 为用户显示的初始数据是否有用? 用户到达屏幕时,应用程序开发者通常希望显示数据。 本行为可使应用看起来更有吸引力并且进行适当演示,但初始列表不常用时其效率较低。 用户预加载大量未经筛选的记录时,这种情况可能导致应用意外缓慢。

  • 应用是否提供正确的数据筛选器? 添加控件以便用户输入条件减少显示行数,有助于用户提高工作效率和性能。

  • 是否因显示相关数据而产生开销? 如果使用提供关系数据访问权限的数据源并且使用库中的相关值,应用可能会对显示的每行执行查找查询。 您可以使用监视器运行应用并查看结果来识别本问题。 将相关数据预加载到集合中并在集合中查找可以提高效率。

  • 您是否知道哪些数据属于静态数据,哪些数据经常更新? 考虑预加载数据之前,务必确定数据是否经常更新。 缓存不经常改变的数据或静态数据可在显示屏幕时准备好数据,有助于提高应用程序的性能。 缓存经常改变的数据可能会对应用程序的性能产生不利影响,也有可能为用户显示过时数据。

  • 是否要为用户显示加载指示器? 如将来自于连接器的数据直接绑定控件,您无法像在集合中缓存数据那样选择显示和隐藏加载指示器。

  • 从数据源加载多少数据? 如果考虑缓存,确保要缓存的数据源的行数不超过应用设置中配置的数据行限制。

  • 是否需要计算列或操作加载的数据? 如果数据源支持所需计算并且列在多个应用中有用,请尝试在数据源中实施这些列。 例如,Microsoft Dataverse 具备计算和汇总列功能。

  • 查看其他应用或自动化添加/修改数据的频率如何? 如将数据预加载到集合中,重新加载集合时仅显示更新的信息。

直接数据源绑定

将库的项目属性设置为表格连接器的表或使用基于表的 Filter() 函数等表达式,您正在执行直接数据源绑定。 以下表达式直接绑定 Desks 表。

SortByColumns(Filter([@Desks], StartsWith(Title, TextSearchBox1.Text)), "Title", If(SortDescending1, Descending, Ascending))

这种方法是数据加载的基本方法。 筛选器上的条件发生变化时,直接从连接器检索数据。 这种方法以声明的方式加载数据,由 Power Apps 运行时决定加载和刷新数据。 因此,您无法选择为用户显示加载指示器。

加载数据后控件即可使用数据,无需每次从数据源检索数据。 您可以使用刷新 (tableName)手动刷新数据源的数据。 在应用中其他位置修改数据时,自动刷新控件中显示的数据。

直接绑定的另一项显著优势在于连接器支持委托时,不受数据行限制应用设置的限制。 例如,如果 Microsoft Dataverse 中包含 100,000 个联系人行并且将库直接绑定到表,库将加载一组初始项目,然后在用户滚动时获取更多项目。 以下屏幕截图显示监视器事件,其中包括调用getRows加载初始数据,随后在用户滚动库时多次调用getMoreRows。 这些调用由 Power Apps 自动完成,应用无需处理数据分页。

显示包含三列的监视器事件的屏幕截图。

如上文所述,您不希望为用户显示 100,000 行。 相反,对于支持委托的数据源,您可以添加筛选器,然后让连接器处理筛选条件,仅返回匹配的行。

将数据预加载到集合中

将数据预加载到集合中允许您控制App.OnStartOnVisible属性中的数据量。 如需在多个屏幕上使用相同的数据,在App.OnStart中预加载数据是不错的选择。 另外,从OnVisible预加载数据允许您推迟到使用屏幕时加载数据。 这两种选项都允许您在加载数据时显示加载指示器。

以下表达式可以清除 colDesks 集合,将所有 Desks 表行加载到数据行限制应用设置。

ClearCollect(colDesks,Desks)

要使用预加载的数据,请更改相关公式以使用集合。

树视图 > 屏幕菜单的屏幕截图,其中突出显示更新的公式。

使用预加载到集合中的数据时,再次使用 ClearCollect() 函数引入最新数据时才会刷新数据。 本场景不同于 Power Apps 自动管理刷新的直接数据源绑定。

这种方法的另一项优势在于您可以允许用户修改和审阅多行,而无需使用数据源保存每行。 完成更改后,您可以使用单个 Patch() 函数调用将更改提交回数据源。 如要在提交前撤消所有更改,您可以刷新集合。 以下示例展示使用 Patch() 函数将 colDesks 集合中的更改提交回 Dataverse 中的 Desks 表的流程。

Patch(Desks,colDesks)

从持久化存储加载

简单预加载方法的变体是先从设备的本地存储加载数据,然后继续直接从数据源加载数据。 数据源速度缓慢或间歇性可用时,本策略很有帮助。 要实施这种模式,请按照以下步骤操作:

  1. 使用 LoadData() 函数从设备的本地存储加载数据(如果存在)。 此时,所有绑定到集合的控件都将显示数据。

  2. 直接从数据源连接器将数据加载到同一集合中。 此时,所有绑定到集合的控件都将显示从连接器加载的更新数据。

  3. 使用 SaveData() 函数将最新数据保存到设备的本地存储。

公式将类似于以下公式:

LoadData(colDesks,"LocalDesks",true);

ClearCollect(colDesks,Desks);

SaveData(colDesks,"LocalDesks");

如果用户偶尔断开连接,可在尝试加载新数据之前添加检查用户是否连接的条件。 经过修订的公式将类似于以下公式:

LoadData(colDesks,"LocalDesks", true);

If (Connection.Connected,

ClearCollect(colDesks,Desks);

SaveData(colDesks,"LocalDesks")

)

预加载到变量中

使用 Office 365 Users 等非表格连接器时,您可将函数调用结果保存到变量中来提高性能。 在以下示例中,公式调用函数三次从配置文件中获取信息:

Set(profileDisplayName,Office365Users.MyProfileV2().displayName);

Set(profileHireDate,Office365Users.MyProfileV2().hireDate);

Set(profileCity,Office365Users.MyProfileV2().city);

以下表达式效率更高,因为仅调用连接器一次,但仍填充三个变量:

Set(profile,Office365Users.MyProfileV2());

Set(profileDisplayName,profile.displayName);

Set(profileHireDate,profile.hireDate);

Set(profileCity,profile.city);

您还可以将其进一步简化为名为配置文件的变量,然后在需要时使用点符号访问属性。例如使用profile.hireDate属性代替profileHireDate变量。 为此,您仅在App.OnStart中使用以下表达式:

Set(profile,Office365Users.MyProfileV2());

然后,使用If(IsBlank(profile.hireDate),Red,Green)表达式(使用点符号profile.hireDate)代替If(IsBlank(profileHireDate),Red,Green)(使用单个变量设置控件颜色)。

同时加载数据

如果从连接器预加载数据并且缓冲多个项目,这些项目默认依次运行。 以下示例展示将两个表和用户配置文件加载到集合和全局变量的流程。

ClearCollect(colDesks,Desks);

ClearCollect(colDeskFeatures,'Desk Features');

Set(userProfile, Office365Users.MyProfileV2())

如果各表独立预加载数据,您可以使用 Concurrent() 函数并行运行各表。

Concurrent(

ClearCollect( colDesks,Desks ),

ClearCollect( colDeskFeatures, 'Desk Features' ),

Set( userProfile, Office365Users.MyProfileV2() )

)

加载数据一次

如在App.OnStart中预加载数据,则仅在应用启动时运行一次。 如改用OnVisible属性推迟加载到第一次使用屏幕时预加载,每次导航到屏幕时OnVisible都将运行。 这种方法可能会过于频繁地刷新集合。 要避免这种情况,您需要先检查是否已加载数据而非执行 ClearCollect() 函数。

ClearCollect(colDesks,Desks)函数调用替换为包括检查集合是否为空的If(IsEmpty(colDesks),ClearCollect(colDesks,Desks))表达式。

应用设置和数据加载

如上文所述,应用设置会影响应用的性能和行为。 如果使用集合预加载数据,数据行限制适用,使较大的数据集不适合预加载。

另一项需要注意的设置是延迟加载。 本设置延迟到需要时运行屏幕表达式调用并且按需要运行。 所有新应用默认打开本设置,可以手动打开较早应用的本项设置。

每款应用的数据加载优化方法都不尽相同。 本主题介绍如何评估用户和应用的需求,根据最佳性能和用户体验定制数据加载策略。 优化无法一蹴而就,需要在应用的生命周期内不断进行。 此外,您还可以使用新推出的优化数据加载的平台功能。