Performance in CRM is only a problem when performance is a problem
I have been doing some work on performance of some CRM forms in CRM 2011. When the topic of performance crops up people the topic of when you should focus on performance won’t be far away.
I’m assuming you haven’t put in the terrible performing code, customizations or processes and you have tidied/refactored customizations to a good standard. In this scenario I only look into improving performance if there is a problem with performance or the customer isn’t happy with performance.
I can hear some of you thinking
Isn’t it better to make your CRM system run as fast as possible?
Yes of course it is, a faster CRM system is better than a slower a CRM system but is this a priority to the customer. If the customer is happy with the speed of the CRM system and the current customizations then the customer would benefit more from a system with less bugs and/or have more functionality they would like.
The cost of spending time on optimizing your Microsoft dynamics CRM solution can take quite a long time for a small benefit of a second or half a second on some forms.
Law of diminishing returns
The usual process of optimizing solutions in CRM is there are some big performance gains in maybe 10 percent (or lower) of the CRM system, these can be found usually in
- Business process
After the initial great gains the effort increases and the reward (time saved) gets smaller and smaller, which is the law of diminishing returns
I like to think of the law of diminishing returns as the bacon sandwich conundrum. I bacon sandwich is magnicant but the second bacon sandwich is ok, additional bacon sandwiches get lower on the tastometer, which is a crime agaisnt bacon sandwiches.
I digress because this blog post is about the performance of Forms in CRM 2011.
Focus on the slowest forms
In a CRM system there are lots of forms you can look at improving the performance of, so where should you start. The main forms you should concentrate on
The slowest forms
The most used forms which are slow
The forms you should focus on first are the slowest forms because these have either the biggest problems or the most problems. The worse performing forms are likely to have the biggest gains.
The way I have been doing this was seeing how long it took the forms to load and what traffic
Common Culprits of slow form loading
The main culprits of slow loading forms are
- Too many subgrids
- Lots of oData/fetchXML queries
- Tabs, sections and fields not needed on the form
- bad/slow coding
To start the code optimization, the first step was to find the bottlenecks and worst performing forms. The next step was to get a benchmark to see how they were loading, to get an average we loaded the form 5 times and the results were quite varied.
We had our list of worst performing forms and we had a quick look at them and made some quick notes
- How many unfiltered OData retrieves
- How many OData calls, where they retrieving the same set
- Number of ribbon buttons
- potential fields/functionality which could be removed by change of business process
Tactics – finding those slow form
One of the tools I used to analyize the slow loading CRM forms was fiddler. I wrote a blog post about Getting Started with Fiddler and CRM. It’s a great tool to see what calls are being made from the page, how long they took and how much data they were bringing back.
Looking at the fiddler logs I was able to investigate the OData queries and find
- Which OData calls took the longest
- Find OData calls which were not filtered
- Find OData calls which were retrieving the same data multiple times
- general loading times of sections of code
We are using two main methods to find slow loading code
Looking at the code
Stepping through the code
How to speed up form loading
Does the customer/end user need all the functionality and fields on the form
Ask the customer to re-evaluate the fields and functionality on the forms.
In some of the forms we were retrieving fields from related entities but to speed up the form the customer was happy to use lookups and click those for more information if it was needed. This saved OData queries
Improvements can come from moving fields and subgrids into unexpanded tabs where the loading can be delayed until the tab is expanded
Subgrids take time to load and the more subgrids you have on a form the longer it will take to load.
Form load time can be saved by putting the grid in an unexpanded tab, this will not load the grid on the form load but will load it when the user expands the tab.
Remove unwanted/unused fields
CRM Developers have to refactor their code then I think CRM Forms and entities should be refactored to remove the noise of unused fields.
There is a great tool to help you with this called CRM Data Detective it will show you what fields are being used/not used by seeing if any values were written to those fields. The CRM Data Detective is a free tool which works with CRM 2011 and CRM 2013.
OData queries are a great way to retrieve data from related fields but if a form has a lot of them they can slow it down. If you use OData queries makes sure they are as lean as possible by filtering them. Below are some tips for using OData queries
- ALWAYS filter your OData queries to retrieve only the fields you need
- Group OData queries to avoid multiple OData queries
Often the first step in writing code is getting it to work, so I can forgive initial code to look ugly and speed along like a one legged tortoise.
It’s unforgivable for the CRM developer not to refactor this code. CRM developer should keep their standards high and not slack off adding dodgy code but this is very frustrating to other team members who will then have to dry and debug it and find it very difficult.
Unrefactored code creates technical debt and this will have to be paid at some point. You don’t save time but putting in sloppy code, you cost the team more time later when debugging and extending that code will take a lot longer than it would if the code had been refactored.
How to avoid slow code
Developers code improves by about 70 percent when they know someone else is going to review it (a statistic I just made up but 100 percent true). I’m not saying Developers can be lazy but often time restrictions and a promise tidy the code up later (which rarely happens) will allow some basic poor coding to slip in.
If a developer knows someone is going to scrutinise their code (or even the threat it) the developer finds time to refactor the code because if hey don’t they know it will be looked at and then told to tidy it up.
Peer reviews can be seen by some developers as a bad thing but it’s a good way to learn new programming techniques and best practices. The ultimate benefit is having more eyes look at some code will stop a lot of bugs sneaking in and keep coding standards high, both of which will benefit the project in the long term.
This article has Developer’s guide to peer reviews highlights some of the benefits
- A different perspective. “Another set of eyes” adds objectivity. Similar to the reason for separating your coding and testing teams, peer reviews provide the distance needed to recognize problems.
- The ability to assess and accelerate progress. Is the team producing the needed output at the needed rate?
- Pride/reward. Recognition of coding prowess is a significant reward for many programmers.
- Project/module familiarity. Everyone involved in the review becomes more familiar with the project and the module.
- Less rework. Do it right the first time. Changes cost more later in the life cycle. The peer review process catches many errors before they go to production.
- Fewer bugs. It’s better to discover your own problems than to have someone (like a user) point them out to you. For the same reason, you may find that many bugs will be eliminated before the code comes to be reviewed by peers.
- Improved communication. More opportunities for interaction tend to lead the team toward improved communication.
- Team cohesiveness. Working together helps draw team members closer. It also provides a brief respite from the isolation that coding often brings.
Companies should coding standards, otherwise the worms are well and truely let out of the can and once those worms are out it’s very hard to get them back in.
Creating coding standards lets the developers know they are expected to code to a standard and there is no excuse for the developers not knowing what the standards are.
Coding standards will also resolve conflicts of style because everyone is expected to code to the agreed company standards.
When I was a Java developer I use to love have my bracket on an If statement on the next line
when Microsoft and other standards have it like this
This is a minor point but when you are looking at 1000’s of lines of code it can make a difference, particularly when it’s not just this small change but lots of others. Suddenly you are in a situation where one persons code is formatted (with different variable names) completely differently making it harder to read, understand, debug and extend the code later.
Coding standards documents are great gift to new developers starting (and then constantly referring them to :-)) because it highlights how they are expected to write code and potential feedback from peer reviews.
Coding standards will help create code consistency not only between different developers but also between projects, which makes it easier for developers to switch between projects.
Create common libraries then it only has to be written once (and well) and then used again and again.
The advantage of writing code once and used in many places is easy to maintain, debug and extend and you only need to test it once.
if there is a bug you only have to fix it one place.
Sometimes it takes more time to generalize a method but in the long run it will save you time.
Why have I put this in a blog about form loading, if you optimize this code it will save time in all the CRM forms it’s used.
Always filter queries
There is no excuse for getting all the fields back in a query because you never use all the fields and the CRM developer is just being lazy.
Split loading times
Evalulate if you need all the data and checks to be done on the form load. It’s possible you could move some of the functionality to
- Unexpanded tabs
- Onchange events
You can put a subgrid in an unexpanded tab and load the subgrid when the tab is expanded. If you have optionsets or other fields which need to be calculated using retrieved fields then these can also be triggered on expanding the tab. This saves time from the form loading.
This would also save time if the tabs included Maps and iFrames.
For some functionality it might be possible to delay some code and remove it from the form onload to a field onChange event.