Visualforce coding best practices

Visualforce is a markup language for building user interface in Salesforce. It has some build in tags starting with “<apex:”. But these tags are finally rendered as HTML tags in UI. So if you have a good understanding in HTML, CSS and JavaScript, you can easily manipulate visualforce to give look and feel of anything possible in pure HTML. All HTML coding best practices are valid for visualforce pages also. In addition to that, please find below some best practices that are usually followed while coding visualforce pages.
  • Try to keep the view state of the page at minimum. Viewstate is basically an encrypted hidden field in the page, which contains the state of controller instance in salesforce server. It is useful for maintaining state between stateless http calls. Viewstate is created when there a form tag is present in the page. It can slow down page, if not taken care properly. Declare variables that are not needed between server calls(where state does not need to be maintained) as transients. It will not be counted against your view state limit of 135kb.
  • Never  hard code drop down values in page. Use it from controller. Also if the values are corresponding to a picklist field in the backend try retrieving, it from metadata so that in future also if some new values are added to it, it will reflect in page automatically. 
  • Render css in the page head and JavaScript at the end of the page to improve page load time.
  • Follow generic HTML web designing best practices like minifying css and JavaScript, optimizing images for web etc. Use sprites (Single big image consolidating multiple single images for css to decrease number of requests)
  • Use Cache, CDN capabilities to improve performance. If your page is not delivering dynamic content, you can increase cache value so that more data is retrieved from cache.
  • Never iterate over large collections. If collection size will exceed 1000, implement pagination. Trying to display more than 1000 will cause visualforce error. If at any time there is need to iterate over large data volume use pagination.
  • Try to decrease queries in constructor and getter methods to improve page load time. Use Ajax to load additional data.
  • If any apex controller variable/property is used in JavaScript in visualforce, encode it using {!JSENCODE(variable)}, to avoid breaking of JavaScript. Otherwise if single quotes are there in the property string, it will cause JavaScript to fail.
  • Try to use AJAX rerendering wherever applicable, instead of posting the full page content to sever. I will give faster response.
  • If page load is taking too long, try to execute some logic asynchronously using AJAX.
  • When using wrapper classes or inner classes for getting UI enhancements, post all content only if needed. For partial effects in the page if entire list of wrapper classes are passed to the controller methods, it will affect performance. Consider using action functions in such cases.
  • Implement complex and highly interactive pages using JavaScript remoting/ visualforce remoting. It will take more time in development but page will be fast as there is not viewstate. Also you can make it more flexible. 

Salesforce Apex Best Practices

Apex is the programming language used in Force.com platform.  It is an object oriented language with syntax similar to Java and working like database procedures. It is a powerful language which in conjunction with Force.com platform can help to build powerful applications with development time lesser than any other platform available today. Starting code development in apex language is very easy. But we should be very careful while developing in this platform as wrong coding practices will lead to hitting governor limits in Salesforce. Below I am listing some best practices for developing in force.com platform.
  • Apex is case insensitive. Try to follow naming conventions similar to Java. Camelcase can be used for variable names. It is better not to use underscores in variable names, even though it is allowed. If used, it can create confusion with field names in objects which contains underscores. Give one tab indentation as Java.
  • Never use queries (SOQL or SOSL) or DML Statements(Insert, Update, Delete, Upsert) inside loops.  Apex code is running in a multi-tenant environment. So Salesforce has implemented governor limits to avoid one user consuming all resources. Below screenshot shows common governor limits in Salesforce.
apex-limits
You can make only 100 SOQL queries and 20 SOSL queries in one transaction. One transaction includes all the actions that are carried out in one event. If you are calling any methods in helper classes and making some queries in that method, that also will be counted against governor limit. Also you are allowed to do DML operation on only 10000 records in a transaction. If you want to do more, you can go for asynchronous execution methods like Batch classes or @Future methods. But be careful not to call asynchronous methods also inside loops.
  • Bulkify all apex codes if possible. For the code to be efficient and avoid hitting governor limits in force.com platform, you have to bulkify all the codes.  For example check below code. Requirement is to update status of all child records when parent status is completed.


    This code may work fine initially in development if users are creating records from Salesforce UI. But if there are more than 150 child records under one completed parent record. Then this code will hit maximum number of DML queries limit. If we optimize this code we can write it as below.

    Note that query at Line number 4 will executed only once and it will pull all parent and child records.  Also there is only one DML statement at the end. If you cannot manage to achieve this through child query or relationship query, you can achieve this by using collections like Map. But you should be careful in this case, not to hit heap limit.
  • Try to externalize maximum parameters. Never hard code any Ids.  Ids changes between sandboxes (different in dev and production for same record type)Usually developers hard codes some values in code like record type id. It is not advisable. If at any place it is unavoidable, use it through custom labels or custom setting. It will be helpful if later you want to change the value.
  • Never use batch call or @future call or Email invocation in loops. It will result in hitting respective limits. Batches queues up usually. If more than 5 times same batch is queued up, it next queuing attempt will throw exception. Number of @future calls and email invocations that can be done in single transaction is 10. If it is in a loop, chances of exceeding this limit is very high.
  • Aim 100% test class coverage. It is mandatory to have a test class coverage of 75%. But more coverage means, all functionality are working as expected. Also add proper assert statements to assert test results are coming as expected.
  • Do bulk testing for triggers. If you have a trigger in any object, test it for bulk volume of records(at least above 200). This will ensure that your trigger will not fail hitting common limits. Also it ensures that your trigger is bulkified. Use organization independent test data using (seeAllData=false). It will ensure code portability between sandboxes.
  • Use indexed fields in WHERE clause of your queries in triggers. If there is an object that can contain more than 100k records. This is mandatory. Otherwise your trigger will fail, when the total volume of records crosses 100k. This is applicable only for triggers. You can find the details in Working with large SOQL queries.
  • Write test classes covering multiple profile scenarios. Use System.runAs() to run as different users. If any test method looks like reaching limit split it into many testmethods in on class, each covering different scenarios.
  • If in any test class, user data is inserted. append time stamp also to the user name. Usually if it is not append in second deployment onwards, duplicate user name error is thrown and test classes fails.
  • Use Test.StartTest() and Test.StopTest() properly to avoid hitting governor limits. If you are not trying to test triggers, keep all data insertion outside Test.StartTest() and Test.StopTest(). Test.StartTest resets governor limits. But make sure that the code that covers the class, is inside Test.StartTest().
  • Go for apex coding only if unavoidable. If it can be handled in out of the box functionality like workflow rule, approval process etc, try to do in that itself.