Importance of performance in Salesforce development
While you can develop and publish your .NET applications using the Microsoft Azure cloud platform - the thing is, these applications would still be being developed through the standard approaches that are used for standalone & web applications. In this small series of posts, we will take a look at a couple of key differences between doing it that way, and doing it the Salesforce way.
We will also go over and highlight the approaches that you'd be using while developing the applications for Salesforce. While the points in this articles won't teach you to develop per se, nor will they show you the best practices to use, or the really cool hacks of top developers. However, what they will do is they'll bring certain aspects to your attention that I believe to be the most noticeable when switching to Salesforce, and, in my opinion, having that knowledge of these factors is even more powerful.
"Even junior Salesforce developers think much more about the performance of their code, when compared to Middle-Senior .NET developers" - this is my own observation over the last 5 years.
It's not a new discovery that modern laptops and smartphones have been powerful enough to give developers a lot of room for development in terms of dealing with performance issues, and in terms of dealing with imperfections in regular consumer software. However, it has been almost the same for "regular" (non-highload) enterprise solutions, which have been being developed for years - it has been so expensive to refactor and optimize them, that adding additional hardware to handle complex processes was actually a greater bang for the buck. Things started to change when cloud platforms like Microsoft Azure or Amazon AWS appeared - to make the monthly bill smaller, developers had to start making their code better. But again, there still was a lot of space for performance tolerances, because for small applications, the difference in the bills were hardly noticeable, and for complex applications, it was too expensive to optimize the software.
The last point here to make, concerns the platform itself - I started developing with .NET, and let's be honest here, its ridiculously low requirements for entry skills, as well as its incredible development speed allowed me, and millions of other developers and companies throughout the world, to build great applications with relatively low investments. And due to the general idea of the platform - it allows and forgives mistakes in the code, especially performance-related mistakes.
Looking at Salesforce, it is also a high-level development platform with almost the same ideas as those behind .NET, however it does not allow one to ignore performance. You will see this when you are developing your first complex "Hello World" training applications . Salesforce incorporates a huge set of so-called Governor Limits, which are applied to anything based on the Salesforce platform. These limits allow everyone to rest assured that their instance will work equally as smooth with one thousand, or one million records, and they won't affect "neighboring" instances in Salesforce's multi-tenant architecture.
"Optimization" by XKCD
What all of this means, is that when you are starting your development for Salesforce, you should learn about the Governor Limits, and the different ways to bypass or trade them off. And also keep in mind all the best practices of performance from your .NET experience - many of them will help you as well.
While this might sound like an issue - it's a great, fun challenge, and experience to be had!
Stop right there, we're developers, right? Where's the code??? Ok, let's take some time, and look at some very simple examples that you might have already been faced with.
Are you always thinking about the heap size?
In the example below everything looks good - getting some collection from the database and iterating over it.
There are no crazy incorrect things like querying data from the database inside for the loop (if we don't talk about the query itself), but anyway it's not exactly good. In cases where there are more than 200 records in satisfying your query, it would be a waste of a heap to load all of them at once (and this is exactly what would be done in the case above). However, a very small change, which is illustrated below, (you can see the change highlighted in line #3) would force Salesforce to load into the heap small batches of 200 records at a time, which can prevent you from getting runtime exceptions on organizations that have a lot of data
Complex simple database queries
For sure, simple and small queries are very easy to read and write, but usually they're not optimal at all, in terms of performance. The example below is a bit more complex, but more obvious as well:
In this small method we have two mistakes:
- We are doing two queries, when we could do a simple query with a "OR" condition
- We have two loops inside other loops, with a lot of redundant executions
While we can try to resolve both of these issues on their own, it would be much more efficient to implement a complex solution like shown below:
Here we use a single query, to select the accounts with the related opportunities, and then we would have only one loop inside another one. This makes the query a bit more complex, and yet it is really beneficial related to two different Governor Limits.
Thankfully, Salesforce's logs are showing us some bits of profiling information, so we can always pay attention to something, if we're doing bad performance wise:
We would also suggest reading Apex Code Best Practices from Salesforce, as it is a must-have, well-written intro to the best practices in Salesforce development. It also might be very interesting for you to check out this Trailhead (Salesforce's own educational resource) module, created especially for .NET developers - Apply .NET Skills to Salesforce.
Another good piece that will get you started is Apex Naming Conventions, which will help you switch from the .NET style to Java/Apex style.