Power Apps - Canvas - Onstart How to avoid ruining your application
Source: Dev.to
Table of Contents
- 1. Introduction
- 2. The OnStart Trap
- 3. Principles That Keep OnStart Healthy
- 4. Suggested Structure
- 5. Practical Tips
- 6. Final Checklist
- 7. Conclusion
- 8. References
1. Introduction
OnStart runs once when the app loads. It is tempting to treat it like a main() function, but that is where performance and maintainability regress. The goal is to keep OnStart as a thin orchestration layer and push real logic into the formula bar (named formulas, UDFs, tables, and styles).
Microsoft guidance for large canvas apps explicitly recommends using App.Formulas instead of App.OnStart and splitting long formulas into reusable parts. That direction is exactly what this article reinforces (see Build large and complex canvas apps).
2. The OnStart Trap
When OnStart becomes a dumping ground, apps slow down and become fragile. Avoid these patterns:
- Do not place core business logic in OnStart. Define UDFs and named formulas and call them from screens or controls.
- Do not load large datasets at startup. Load only what the first screen needs and defer the rest.
- Do not build long, monolithic formulas in OnStart. Split logic into named formulas and UDFs (see Build large and complex canvas apps).
- Do not call connectors inside loops. This multiplies network calls and kills load time.
- Do not mix unrelated responsibilities. Separate parameters, caching, user context, and UI defaults.
- Do not use OnStart as a hidden workflow engine. This breaks reusability and makes testing harder.
- Do not rely on screen state. Screen‑specific setup belongs in
Screen.OnVisibleor screen‑level UDFs.
3. Principles That Keep OnStart Healthy
Use these principles to keep OnStart small and safe:
Thin Orchestration Only
- OnStart should call setup steps, not implement them.
- Keep reusable logic in
App.Formulasand UDFs.
Deterministic and Idempotent
- Running OnStart twice should not corrupt state or create duplicates.
Fast First Screen
- Load only what is required for the first screen to render (see Overview of creating performant apps).
Separation of Concerns
- Keep environment/params, collections, user context, and theme settings in distinct blocks.
Concurrent Only For Independent Tasks
- Use
Concurrentonly when operations are truly independent (see Efficient calculations).
4. Suggested Structure
/*-----------------------------------------------OnStart-----------------------------------------------*/
// Flow response and parameters
With(
{ coFlow: 'SomeFlow'.Run() },
Set(vsFlowValue, coFlow.result)
);
// Deeplink routing (task focus)
If(
!IsBlank(Param("Source")),
Switch(
Param("SomeParameter"),
"TaskA", /* setup for TaskA */,
"TaskB", /* setup for TaskB */,
Blank()
)
);
// Global defaults and parameters
Concurrent(
Set(vsParamScreen, Param("Screen")),
Set(viParamItemId, Value(Param("ItemID")))
);
// Build month/period lists
ClearCollect(
colPeriodList,
/* data builder logic */
);
// Optional data enrichment (only if needed)
If(
RoundUp(Month(Now()) / 3, 0) = 1,
Collect(colPeriodList, /* additional rows */)
);
// Collections cache (first screen only)
ClearCollect(
colCache,
ShowColumns(SomeDataSource, /* required columns */)
);
/*-----------------------------------------------End OnStart-----------------------------------------------*/
5. Practical Tips
- Use
App.Formulasto split logic and keep OnStart readable (see Build large and complex canvas apps). - Prefer named formulas for read‑only values like constants, configuration, and lookups (see Get started with formulas in canvas apps).
- Use explicit column selection (
ShowColumns) when caching collections to reduce payload (see Efficient calculations). - Prefer delegable query patterns such as server‑side views and
StartsWith/Filterto avoid local loops (see Optimized query data patterns). - Cache only what is reused on multiple screens. If a collection is used on a single screen, load it there.
- Avoid
Patch/SubmitFormin OnStart. Side effects at startup are hard to debug. - Document the intent of each block with short comments.
6. Final Checklist
Before shipping, verify:
- OnStart runs fast and does not load unnecessary data.
- Logic is grouped into clear sections with comments.
- Business rules live in the formula bar (UDFs, named formulas).
- Screen‑specific init is in
Screen.OnVisible, not OnStart. Concurrentis used only for independent tasks.- All external calls are delegable or appropriately cached.
- The app passes the Performance and Maintainability tests in the Power Apps Checker.
7. Conclusion
Treat OnStart as a lightweight bootstrapper: orchestrate, delegate, and stay deterministic. By moving heavy lifting to reusable formulas and keeping data loading minimal, you gain faster load times, easier testing, and a more maintainable canvas app.
8. References
- Microsoft Docs – Build large and complex canvas apps
- Microsoft Docs – Overview of creating performant apps
- Microsoft Docs – Efficient calculations
- Microsoft Docs – Get started with formulas in canvas apps
- Microsoft Docs – Optimized query data patterns
