What it does
Model-driven app performance is dominated by form load: what the default tab has to fetch, what JavaScript runs before the form is usable, and what the client can cache between navigations. The platform gives you Live monitor, Monitor in the maker portal, solution checker and object checker to find out which of those is hurting.
Key facts
- The default tab — the first expanded tab — has all its controls initialised on form load, including data retrieval. Controls on secondary tabs initialise only when that tab is opened, by the user or by
setFocus. - The expensive controls are the ones that fetch beyond the primary record: quick view forms, subgrids, timeline, and the Sales Insights Assistant. Less costly but still relevant: lookups, iFrames and web resources.
- Don't open forms in new windows.
openForm's new-window parameter and directwindow.opencalls both throw away the in-memory client cache and reload every page resource from scratch. Multisession tabs keep the caching benefit. - Form
OnLoadandOnSavesupport handlers returning a Promise and the platform waits, up to a timeout. That's enabled via app settings. FormOnChangedoes not support it — the documented workaround isshowProgressIndicatoraround the async work. - Async continuation is a correctness risk, not just a performance one: by the time the promise resolves the user may have navigated away and the form context may be gone. Check context after every continuation point.
console.logand other console API calls in production code significantly increase memory demand and can prevent memory being reclaimed — the app gets slower over time and eventually crashes.- Memory leak sources to clean up: event listeners and subscriptions (especially on
window), timers likesetInterval, and references to global or static objects. PCF controls clean up indestroy. - Load JavaScript libraries only where they're needed. Don't load a library in
OnLoadif it's only used byOnChangeorOnSave. - Use client API data you already have rather than querying —
getGlobalContext.userSettings.rolesinstead of requesting the user's security roles on load. - Solution checker parses client JavaScript, form XML and server-side plug-ins for performance and reliability issues. Microsoft's advice is to run it on every publish in dev. Example rules:
il-specify-column(don't select all columns),web-use-async,web-avoid-ui-refreshribbon(avoidrefreshRibbonin formOnLoadand enable rules). - Object checker runs real-time diagnostics on solution components and returns fix recommendations. Marked preview.
- Live monitor logs app activity as it runs. Filter the Category column on
formcheckerfor form events — control state, related menu, tab/section/control state changes with the callstack that caused them, navigation and dialogs viaXrm.Navigation, and unsupported client API access before the form is ready. - Monitor in the maker portal covers model-driven apps for app open success rate, app session count and row summary dwell time. Time to interactive, time to full load, data request success rate and data request latency are not available for model-driven apps — those are canvas and code app metrics.
- Recommendations in Monitor are only available in Managed Environments.
- Browser matters. Older and non-Chromium browsers miss platform performance work; switching to a current Chromium-based browser or Edge often improves page load on its own.
When to use / skip
Do this work when users complain, and do it in order: check the default tab layout first, because moving two subgrids to a secondary tab is ten minutes and often the whole fix. Only then go looking at JavaScript. Skip the deep instrumentation on an app with three tables and no custom code — there's nothing to find. The place to spend real effort is an inherited Dynamics environment with years of accumulated form scripts, where solution checker will usually hand you a prioritised list on the first run.
Configuration decisions
- Which controls live on the default tab. This is the decision that moves the needle most, and it's a layout choice with a performance consequence.
- Whether async
OnLoad/OnSavesupport is enabled in app settings, and whether the existing scripts are written to use it correctly. - How JavaScript is split into libraries and which events load which.
- Whether solution checker runs on every publish in dev, and whether its findings actually get triaged or just accumulate.
- Whether the client's browser and device baseline is documented and enforced, or whether you're supporting whatever people happen to have.
- Whether Managed Environments is in scope, since that gates the Monitor recommendations.
Gotchas
- Users and process owners will fill the default tab, because it's the first thing they see. Every subgrid they ask for there is a data call before the form is usable.
- Synchronous network calls in form scripts freeze the form. They're still common in inherited code and they're the most visible performance problem a user experiences.
console.logleft in production is a slow leak, not a harmless artefact. It shows up as "the app gets slower through the day", which is easy to misdiagnose as network or server load.- Async code in
OnChangethat assumes the form context still exists will throw intermittently and be very hard to reproduce. - Note the naming overlap: the older "performance insights" experience now lands on the Monitor page in the maker portal. If a client is asking for performance insights by name, they may mean the older tool.
- Model-driven apps don't get time-to-interactive or data latency metrics in Monitor. If you promised a load-time number from the platform, you'll need Application Insights or browser tooling instead.
Consultant notes
- Run solution checker before you quote remediation on an inherited environment. It turns "the app is slow" into a costed list, and it's free.
- Lead with the default tab conversation in design workshops, before the process owner has emotionally committed to a form layout. Retrofitting it feels like taking features away.
- Warn clients that opening records in new browser windows — which some users do deliberately — is slower by design. Point them at multisession tabs instead.
- Instrument with Application Insights if the client needs actual load-time reporting, since Monitor won't give it to you for model-driven apps.
- Browser standardisation is a genuine performance lever and it's an IT conversation, not a Power Platform one. Raise it early with the right people.
Worth another look if Monitor extends time-to-interactive to model-driven apps, or when object checker leaves preview.