Last week, Microsoft applied updates to improve the performance of apps. This update discourages the
use of App.OnStart and deprecates the use of the Navigate function in App.OnStart.
The preferred method is to use the StartScreen property to specify the screen that we want to navigate to. Traditionally, the initial screen that appears when an app loads is the screen that appears at the top of the Screens section of the Tree view. The StartScreen property now controls the initial screen that appears.
Taking our example, we would set the StartScreen property to the following formula:
This configures the app to display DetailScreen1 if the web address includes an IssueID value. If not, the app displays BrowseScreen1.
The rest of the app remains the same, and the app continues to function as it did previously. This example highlights an example of a simple migration.
Method 2 - Set the StartScreen and disable the 'Use non-blocking OnStart rule'
With Method 1, it might also be necessary to switch off the 'Use non-blocking OnStart rule' setting.
As an example, here's a variation of a deep linking technique that relies on the following App.OnStart formula:
To highlight the necessity of why it's necessary to disable the 'Use non-blocking OnStart rule', let's assume there's a text input control with the text property set to varSelectedRecord.IssueDescription on DetailScreen1. This mimics the typical example of a screen that displays data without the use of a form control.
To modify the app to use the StartScreen method, we remove the call to Navigate in App.OnStart. The updated formula in App.OnStart now looks like this:
Next, we set the start screen property to the following formula:
Whilst this fixes the 'Navigate is not permitted in OnStart' error, there is a problem with this technique. That is - when the app starts, Power Apps executes the App.OnStart formula and displays the start screen simultaneously/asynchronously.
Therefore, it's possible for the app to display the start screen and to display the value varSelectedRecord.IssueDescription in the text input control before it successfully loads the target record in App.OnStart. In this case, the text input control will be empty, which is incorrect behaviour.
One way to fix this problem is to disable the 'Use non-blocking OnStart rule' setting. With this setting disabled, Power Apps will complete the call to LookUp in App.OnStart before it displays the start screen. This resolves this timing problem but unfortunately, it also negates the performance benefit that this change intends to introduce (ie - to speed up the display of the initial screen).
Method 3 - Use a timer control to run the startup formula
The third method is to create a custom start screen, add a timer control, and to add the existing OnStart formula to the timer.
To give a use case scenario, here's another variation of deep linking that relies on a screen/context variable called locSelectedRecord. DetailScreen1 would contain a form with the Item property set to this variable. The App.OnStart formula for this example looks like this:
Because the App.StartScreen property provides no way to pass context variables, the timer method offers a viable workaround. A second alternative would be to rewrite the app to use global variables rather than context variables, however, this could involve a significant rewrite of an app depending on the number of places where we set/use the context variable.
To implement the timer method, we would add a new screen to the app (let's call this StartScreen). We set the App.StartScreen property to StartScreen.
From the StartScreen, we add a timer control. We set the Duration property to 1, the AutoStart property to true, and we can also hide the timer by setting the Visible property to false. We can also customise the look of this screen so that it looks like an interstitial, or "splash screen" - that is, a screen that contains some visual indication that the app is loading.
We then cut and paste the existing App.OnStart formula into the OnTimerEnd property.
At startup, the app immediately shows StartScreen and milliseconds later when the timer triggers, the app will
execute the startup formula.
The advantage of this method is that it offers a relatively simple solution that involves minimal refactoring/rewriting of an app. This can be appropriate for apps with very complex OnStart logic because splitting the logic between App.OnStart and App.StartScreen may not be trivial and can be exacerbated by existing formula in the OnVisible property of the target start screen. Orchestrating these 3 threads to minimise dependencies and to ensure all the formulas run in the expected sequence can be difficult.
One disadvantage of this technique is that it adds additional time to the startup of an app, which can be noticeable.
Note that on the topic of context variable support, I've added an idea here to add the ability to pass context variables to App.StartScreen.
Method 4 - Re-enable Navigate in App.OnStart through the settings
The final technique is to re-enable Navigate in App.OnStart through the settings.
This is by far the easiest solution to the immediate problem. However, this switch will be available for a limited time only, and at some point in the future, we'll need to modify our app to properly remove the call the Navigate in App.OnStart.
An update to Power Apps now makes it impossible to call the Navigate function from App.OnStart. This has a big impact on apps that implement deep linking functionality, and this post describes four techniques to resolve this issue.