PowerApps Optimization Techniques
At Microsoft Business Applications Summit, I had a chance to put in practice some of the Optimization concepts techniques I outlined last year in this blog post: https://powerapps.microsoft.com/en-us/blog/performance-considerations-with-powerapps/ .
In the session, I took a low performing conference app and applied few of those optimization techniques. You can see here side by side the substantial improvement.
Conference App Overview
A conference app is a common scenario we see many organizations build for their internal events. In our case here, the app was built on top of SQL using the default SQL connector. However, the optimization techniques used here are transferable to any other data source such as SharePoint or CDS.
Here is the object diagram of the various tables used in this app:
As the number of tables and relationships increases, the complexity of the app increases as well with the potential degradation of performance if special care and attention is not given to how and when we are fetching data from the back-end.
Refactoring how data is initially loaded is probably the single most important step that will lead the most performance gain. The goal in mind should always be about how to get the user interacting with app as soon as possible. You can see here how I went about dealing with my network calls on App Start, On Visible and within individual controls like the gallery control.
You can see here how I re-order the calls to fetch data in such a way that the required data used in the home screen is loaded within the pre-loader context variable setting. Any other data calls that is not crucial to the home screen is made after we hide the pre-loader animation. This allow the user to interact with the app as soon as possible while the remaining data calls are happening in the background.
The next optimization is around wrapping independent calls within the Concurrent function. You can see it here in action. This ensures that we trigger network calls in parallel rather than serially which is the default behavior when we do a series of ClearCollects sequentially to retrieve data.
Avoiding duplicate network calls is something to watch out for. If there are opportunities to fetch a greater set of the data and filtering locally, that might be better than few network calls to fetch subset of the data. You can see here an example of this.
The product team is working on a feature to enable app makers to see network calls their app is making. Meanwhile, using Fiddler or your favorite browser’s developer tools, you can actually see the calls your app is making to fetch data as you can see in the video here.
In this section of the video, I discuss the importance of compressing images to minimize the time it takes to download them. I also discuss an alternative approach to pre-load images which might be needed in case you don’t have access to source images and therefore pre-optimizing assets (compression) might not be an option.
Persisting data is also something we looked at in this session. Saving data back to the server can take some time. We can take the optimistic approach to assume our save operation will be successful, update our local view of the data in such a way that users see data updates reflected in the user interface right away. The actual save (Patch/Submit) is done in the background.
The idea here is to identify data that is unlikely to change over time and create a static excel sheet version of it. Start the app by loading the data from the embedded static excel sheet (which is internally backed into the app in json format). The same collection can then be updated immediately (possibly after the pre-loader animation is done) by the actual call to the back-end to retrieve the latest version. This technique is not applicable in all situations but can greatly improve the initial load of the app.
App Setting Performance Flags
Finally, there are a number of App Settings that will have a significant impact on your app performance. Check this section of talk to get a quick overview.