In my journey with Microsoft technologies, I've found that applying best practices in Power Apps canvas apps and C# code for Dynamics 365 can make a huge difference in performance, maintainability, and reliability. This blog draws from key guidelines on canvas app optimization and C# coding strategies for business apps. I'll share my insights and rephrased understanding to help you build better solutions.
Power Apps Canvas App Performance Tips
Canvas apps in Power Apps are great for quick development, but to keep them snappy, focus on efficient design. From execution phases to data flows, here are some strategies to enhance speed.
Restrict Data Connections
Keep connections under 30 per app to avoid slow starts from authentication prompts. Each extra connector consumes resources like CPU, memory, and bandwidth during runtime. Use browser dev tools to measure; apps with over 30 often exceed 15-second data returns. Connections are counted per source, like Dataverse or SQL tables.
Constrain the Number of Controls
Limit to 500 controls app-wide, as each adds to HTML DOM rendering time. Use galleries for repeated UI elements to speed up launches. Minimize control types on screens—heavy ones like PDF viewers or combo boxes load large scripts.
Enhance OnStart Property
Cache static data locally with ClearCollect for session-long use. Load multiple sources in parallel with Concurrent to halve loading times.
Sequential load example:
powerappsClearCollect(Product, 'SalesLT.[Product]'); ClearCollect(Customer, 'SalesLT.[Customer]'); ClearCollect(SalesOrderDetail, '[SalesLT].[SalesOrderDetail]'); ClearCollect(SalesOrderHeader, '[SalesLT].[SalesOrderHeader]')
[Image description: Timeline chart showing sequential loading of Product, Customer, SalesOrderDetail, SalesOrderHeader.]
Parallel load:
powerappsConcurrent( ClearCollect(Product, 'SalesLT.[Product]'), ClearCollect(Customer, 'SalesLT.[Customer]'), ClearCollect(SalesOrderDetail, '[SalesLT].[SalesOrderDetail]'), ClearCollect(SalesOrderHeader, '[SalesLT].[SalesOrderHeader]') )
[Image description: Timeline chart showing parallel loading of Product, Customer, SalesOrderDetail, SalesOrderHeader.]
Note: Tune OnStart for performance; see related resources.
Tip: Use App.StartScreen for simpler launches and better speed.
Store Lookup Data Locally
Cache lookups with Set to reduce repeated fetches. Useful for unchanging data like contacts.
Example:
powerappsSet(CustomerOrder, Lookup(Order, Id = "123-45-6789")); Set(CustomerName, CustomerOrder.Name); Set(CustomerAddress, CustomerOrder.Address); Set(CustomerEmail, CustomerOrder.Email); Set(CustomerPhone, CustomerOrder.Phone);
Combine with Defaults and User functions.
Prevent Cross-Screen Dependencies
Load screens on-demand, but avoid control refs across screens to prevent chain loading. Use globals or collections for sharing.
Exception: No issue if navigation ensures prior screen is loaded.
C# Best Practices for Dynamics Extensions
For server-side customizations like plugins or workflows in Dynamics 365, C# code must be clean and efficient. Based on CoE readiness guidelines, here's what to avoid, do/don't, and consider.
Avoids in C#
Steer clear of these to prevent issues.
-
Blocking Calls: Skip Task.Wait or Task.Result in async code; use await instead.
-
Obsolete Constructs: Use modern language features over outdated ones.
-
Mixing Unrelated Functionalities: Adhere to SRP—one responsibility per class/method.
-
String Concatenation in Loops: Opt for StringBuilder for efficiency.
-
Mutable Static Variables: They can cause unexpected state changes.
-
Inefficient Algorithms: Choose optimal ones to avoid leaks and bottlenecks.
-
Unhandled Exceptions: Handle them to prevent crashes.
Do's and Don'ts in C#
Follow these for better code.
Do's:
-
CamelCase variables/methods, PascalCase classes.
-
Prefix "Is" for boolean two-option sets.
-
Use form context for form interactions.
-
Place assignments/initializations outside loops.
-
Employ async data access.
-
Fetch minimal data.
-
Verify attributes before access.
-
Use ==/!= for comparisons.
-
Implement try-catch for error handling.
-
Use 'using' for resource cleanup.
-
Prefer existing exceptions; provide clear messages.
-
Comment methods/classes.
Don'ts:
-
No consecutive underscores in identifiers (reserved).
-
Avoid type-specifying variable names.
-
No unsafe code like Console.WriteLine in certain contexts.
-
Skip abbreviations for prefixes/suffixes.
-
No arbitrary/hardcoded values.
-
Prefer composition over inheritance.
-
Manage resources to avoid leaks.
-
Use var only when type is clear.
-
e.g., int number = Convert.ToInt32(Console.ReadLine);
Considerations in C#
Keep these in mind for robust code.
-
Variable Types: Use prefixes/suffixes like Hungarian notation.
-
Naming Conventions: Follow domain-specific standards.
-
Exception Handling: Use filters and finally blocks.
-
Access Modifiers: Encapsulate with public/private/protected.
-
Object Pooling: For frequent objects to cut allocation overhead.
-
Structs: For small immutable types to boost performance.
-
Input Validation: Multi-layer to block injections.
-
Resource Disposal: Use 'using' for IDisposable objects.
Final Thoughts
Incorporating these practices in Power Apps and C# for Dynamics 365 ensures scalable solutions. Always test and iterate based on your scenario. For more, explore Microsoft Learn resources on canvas apps and C# guidelines.