Optimize code app performance and resource usage
Unit 4's telemetry pointed at a specific screen: the coordinator's request list, which brings together employee, device, and allowance data in one view. That screen takes longer to become interactive as more employees use the app, and NetworkRequestMetricData shows large, frequent calls to Dataverse behind it. This unit explores how to act on that signal, reducing how much data the app asks for and how often. That way, time to interactive and data request latency improve as usage grows.
Where the data cost actually comes from
A code app's runtime splits into three layers: your own code, the Power Apps client library, and the Power Apps host. The host handles authentication, app loading, and presentation. The client library is the generated service layer, the typed models and methods (for example, RequestsService.ts) that the Power Apps CLI creates in /generated/services/ the moment you connect a Dataverse table.
Neither of those two layers decides how much data a screen pulls back. That decision lives entirely in your code, in the options you pass when you call a generated service's getAll() method.
That distinction matters because it means request volume and size aren't something the platform tunes for you after the fact. If the request list screen calls getAll() with no options, it retrieves every column for every row the current user can see, every time the screen loads. The platform doesn't rewrite that call into something leaner. Your code is the only place that choice gets made, which also means it's the only place you can fix it.
Ask for less: select, filter, and sort server-side
The getAll() method accepts an optional IGetAllOptions object, and the most direct lever in it is select, which limits the response to specific columns instead of full rows. Microsoft's own guidance here is explicit: always limit the number of columns you retrieve by using select. For the request list, that means asking only for the employee name, device type, allowance balance, and request status the screen actually displays, not every field the request, employee, device, and allowance tables contain.
select reduces the size of each row. filter and orderBy reduce how many rows come back at all, and both are delegated. That means Dataverse applies them on the server before any data crosses the network, rather than the app pulling everything down and filtering it in the browser.
A coordinator reviewing the queue rarely needs the entire request history, only the open or pending requests. A filter that narrows to those statuses server-side removes rows the screen never needed to transfer in the first place.
const options: IGetAllOptions = {
select: ['employeename', 'devicetype', 'allowancebalance', 'status'],
filter: "status eq 'Pending'",
orderBy: ['submitteddate desc']
};
const result = await RequestsService.getAll(options);
Adapted this way, the request list asks Dataverse for exactly the columns it renders and exactly the rows the coordinator needs to act on, instead of the full table.
Learn more about connecting a code app to Dataverse.
Ask for it in pieces: paging instead of one large pull
select and filter shrink each response, but a growing request history eventually means the pending queue itself is large. That's where paging comes in: IGetAllOptions also supports maxPageSize, top, skip, and skipToken, which retrieve a large table incrementally instead of in one pull.
A getAll() call with no options is tolerable while Contoso's request table is small. As submissions accumulate across more employees, that same unbounded call becomes a liability. Every load of the request list drags along months of resolved requests the coordinator isn't looking at today.
Set maxPageSize or top to a number that matches what the screen shows on one page. Use skip or skipToken to retrieve the next page only when the coordinator asks for it. Together, these keep each individual network call small, regardless of how large the underlying table grows.
The judgment call is which lever to reach for first: select and filter address a screen that pulls too much per row or too many irrelevant rows; paging addresses a screen whose relevant row count itself keeps growing.
Resource-usage symptoms, not just slow ones
Not every heavy request shows up as a perceived delay. SessionLoadSummaryMetricData's appLoadNonOptimalReason field includes a value, throttled, that signals the app hit a rate limit rather than simply running slowly.
That's a resource-usage problem, not a speed problem, and it has a documented counterpart in the Monitor page's Data request success rate metric: a high rate of failures paired specifically with an HTTP 429 status correlates with network throttling from too many data calls. The recommendation tied to that pattern is the same lever this unit already covers, reduce the volume of data the app requests.
This is also the reason "optimize performance" and "reduce resource usage" describe the same work rather than two separate ones. A screen that issues fewer, smaller, well-targeted Dataverse calls becomes interactive faster, and it's also less likely to get throttled as more employees use it at once.
Guiding question: The request list's
NetworkRequestMetricDatashows a call with a largeresponseSizebut a normalduration. A different session showsappLoadNonOptimalReason: throttled. Which fix from this unit addresses each symptom, and why wouldn't the same fix necessarily help both?
Confirm the improvement
Once a change ships, the same three tools from the previous unit tell you whether it worked:
- DevTools: filter the Network tab by
dynamics.comon the request list and compare how many calls fire and how large the responses are before and after. - Application Insights:
NetworkRequestMetricData'sdurationandresponseSizefields give you the same comparison across real sessions rather than just your own browser. - Monitor: time to interactive and data request latency are the two metrics most directly affected by narrower
selectandfiltercalls and by paging.
That makes them the right before-and-after numbers to track as Contoso's request volume keeps growing.
With the request list now asking for less and asking for it in pieces, Contoso's equipment-provisioning app is deployed, secured, observable, and tuned to stay responsive as adoption grows. That's where this module's knowledge check and summary pick up.