Troubleshoot & Optimise Apps
When apps misbehave or run slowly, you need the right tools. Learn to diagnose issues with Monitor and browser dev tools, and optimise performance with delegation-aware queries and form tuning.
Finding and fixing problems
Think of debugging like being a doctor.
A patient says βmy arm hurts.β You do not guess β you examine, run tests, and look at X-rays. The Monitor tool is your X-ray machine for Power Apps. It shows you exactly what is happening behind the scenes: every data call, every formula evaluation, every error.
Performance optimisation is like a health check-up. The app works, but is it efficient? Is it making unnecessary trips to the server? Is it loading 10,000 records when the user only needs 10? Delegation is the key concept β it determines whether your query runs on the server (fast) or pulls everything to the client and filters locally (slow).
Debugging with Monitor
The Monitor tool captures everything your app does behind the scenes.
| What Monitor Shows | Why It Matters |
|---|---|
| Network requests | See every call to Dataverse, connectors, and APIs β including timing and payload size |
| Formula evaluations | Which formulas are running, how long they take, and what they return |
| Errors and warnings | Detailed error messages that may not appear in the app UI |
| Delegation warnings | Which queries are running client-side instead of server-side |
| User actions | Track what the user clicked and the resulting data flow |
Common debugging patterns
- App returns wrong data β Check Monitor for the network request. Is the filter correct? Is the query delegated?
- App is slow β Sort Monitor events by duration. Find the slowest network requests.
- Intermittent errors β Run Monitor with βJoin sessionβ to capture a userβs live session remotely.
- Connector failures β Monitor shows the raw HTTP response including error codes and messages.
Scenario: Kai debugs a slow shipment app
Kaiβs shipment tracking app takes 15 seconds to load the main screen. He opens Monitor and sees:
- Three sequential Dataverse queries β each takes 3-4 seconds. They load Shipments, Drivers, and Vehicles.
- A delegation warning on the Shipments query β the filter uses a
Left()function, which is not delegable. Dataverse returns only the first 500 records, then the app filters 10,000 records locally. - A large payload β the Drivers query returns all 50 columns when the screen only displays Name and Phone.
Fixes:
- Replace
Left()filter with a delegableStartsWith()function - Use
Concurrent()to load all three queries in parallel - Add
ShowColumns()to the Drivers query to fetch only Name and Phone - Result: load time drops from 15 seconds to 3 seconds
Delegation: the performance killer
Delegation means the data source (Dataverse, SQL, SharePoint) processes the query server-side. If a formula is not delegable, Power Apps downloads all records and filters locally β with a cap (default 500, max 2,000).
| Function | Delegable to Dataverse? | Alternative |
|---|---|---|
| Filter with =, <>, <, > | Yes | N/A β use these |
| StartsWith | Yes | N/A β use this for text matching |
| Search (in view) | Yes | Use Dataverse search for best results |
| Left, Right, Mid | Yes (Dataverse) | Note: delegable to Dataverse but NOT to SharePoint or SQL β check per data source |
| Len | Yes (Dataverse) | Delegable to Dataverse; not all sources support it |
| in operator (collection) | No | Use AddColumns + LookUp pattern instead |
| IsBlank (on lookup) | No | Filter on the lookup column directly |
| Sort with formula | Partial β simple column sorts are delegable | Add a sort column in Dataverse |
Pre-loading data
For data that does not change during a session, load it upfront:
- Named formulas β define in App.Formulas for automatic caching
- Concurrent() β load multiple data sources in parallel on App.OnStart or screen OnVisible
- Collections β
ClearCollect(LocalCache, Filter(BigTable, ...))to create a local copy for non-delegable operations
Exam tip: The delegation warning trap
The exam often presents a scenario where an app works correctly in testing (small dataset, under 500 records) but fails in production (large dataset, 10,000+ records). The cause: a non-delegable formula that silently drops records beyond the delegation limit.
The fix is always: use delegable functions, increase the delegation limit (Settings β max 2,000), or pre-filter with a delegable query before applying non-delegable transformations.
Model-driven app optimisation
Form performance
| Optimisation | Impact |
|---|---|
| Remove unused tabs and sections | Fewer components to render |
| Lazy-load tabs (expand by default = off) | Tabs load only when clicked |
| Minimise JavaScript on form load | Reduce OnLoad execution time |
| Batch Web API calls | One request instead of multiple |
| Use business rules instead of scripts for simple logic | Faster, no JavaScript overhead |
View performance
- Limit columns β show only what users need (each column is a query join)
- Add appropriate filters β avoid βall recordsβ views on large tables
- Use personal views for individual needs instead of modifying system views
A canvas app displays a gallery of Customer records filtered by the first three characters of the customer name. The app works correctly with 200 test records but shows incomplete results in production with 15,000 records. What is the most likely cause?
π¬ Video coming soon
Next up: Client Scripting β writing JavaScript for model-driven app form events, the Client API, and Dataverse Web API calls.