Apex Best Practices
- Do not use hardcoded IDs
- No DML statements inside loops
- No SOQL or SOSL queries inside loops
- Use Apex Limits Methods to avoid hitting governor exceptions.
- Use SOSL over SOQL where possible – it’s much faster.
- Apex code must provide proper exception handling.
- Prevent SOQL and SOSL injection attacks by using static queries, binding variables or the escapeSingleQuotes method.
- Asychronous Apex should be “bulkified”.
- Use Asychronous Apex (@future annotation) for logic that does not need to be executed synchronous.
- Since Apex is case insensitive you can write it however you’d like. However, to increase readability, follow Java capitalization standards and use two spaces instead of tabs for indentation.
Triggers Best Practices
- There should only be one trigger for each object.
- Avoid complex logic in triggers. To simplify testing and reuse, triggers should delegate to Apex classes which contain the actual execution logic.
- Triggers should be “bulkified” and be able to process up to 200 records for each call.
- Execute DML statements using collections instead of individual records per DML statement.
- Use Collections in SOQL “WHERE” clauses to retrieve all records back in single query
- Use a consistent naming convention including the object name (e.g., AccountTrigger)
Visualforce Pages Best Practices
- Do not hardcode picklists in Visualforce pages; include them in the controller instead.
- Javascript and CSS should be included as Static Resources allowing the browser to cache them.
- Mark controller variables as “transient” if they are not needed between server calls. This will make your page load faster as it reduces the size of the View State.
- Use <apex:repeat> to iterate over large collections.
- View State SizeThe view state size of your Visualforce pages must be under 135 KB. By reducing your view state size, your pages can load quicker and stall less often.
You can monitor view state performance through the View State tab in the development mode footer and take the following actions:
- Use the transient keyword in your Apex controllers for variables that aren’t essential for maintaining state and aren’t necessary during page refreshes.
- If you notice that a large percentage of your view state comes from objects used in controllers or controller extensions, consider refining your SOQL calls to return only data that’s relevant to the Visualforce page.
- If your view state is affected by a large component tree, try reducing the number of components your page depends on.
- Load TimesLarge page sizes directly affects load times. To improve Visualforce page load times:
- Cache any data that is frequently accessed, such as icon graphics.
- Avoid SOQL queries in your Apex controller getter methods.
- Reduce the number of records displayed on a page by:
- Limiting the data coming back from SOQL calls in your Apex controllers. For example, using ANDstatements in your WHERE clause, or removing null results
- Taking advantage of pagination with a list controllerto present fewer records per page
- “Lazy load” Apex objects to reduce request times.
- Consider moving any JavaScript outside of the <apex:includeScript>tag and placing it into a <script> tag right before your closing <apex:page> The <apex:includeScript> tag places JavaScript right before the closing <head>element; thus, Visualforce attempts to load the JavaScript before any other content on the page. However, you should only move JavaScript to the bottom of the page if you’re certain it doesn’t have any adverse effects to your page. For example, JavaScript code snippets requiring document.write or event handlers should remain in the <head>element.
- Multiple Concurrent Requests
Concurrent requests are long-running tasks that could block other pending tasks. To reduce these delays:
- Action methods used by <apex:actionPoller>should be lightweight. It’s a best practice to avoid performing DML, external service calls, and other resource-intensive operations in action methods called by an <apex:actionPoller>. Carefully consider the effect of your action method being called repeatedly by an <apex:actionPoller> at the interval you specify, especially if it’s used on a page that will be widely distributed, or open continuously.
- Increase the time interval for calling Apex from your Visualforce page. For example, when using the <apex:actionPoller>component, you could adjust the interval attribute to 30 seconds instead of 15.
- Move non-essential logic to an asynchronous code block using Ajax.
- Queries and Security
By using the with sharing keyword when creating your Apex controllers, you have the possibility of improving your SOQL queries by only viewing a data set for a single user.
Preventing Field Values from Dropping Off the Page
If your page contains many fields, including large text area fields, and has master-detail relationships with other entities, it may not display all data due to limits on the size of data returned to Visualforce pages and batch limits. The page displays this warning: “You requested too many fields to display. Consider removing some to prevent field values from being dropped from the display.”
To prevent field values from being dropped from the page, remove some fields to reduce the amount of data returned. Alternatively, you can write your own controller extensions to query child records to be displayed in the related lists.
Unit Testing Best Practices
- Test classes should use the @isTest annotation
- Test methods should create all data needed for the method and not rely on data currently in the Org.
- Use a consistent naming convention including “Test” and the name of the class being tested (e.g., Test_AccountTrigger)
- Do not use SeeAllData=true because in other org that data will not be present.
- Use System.assert liberally to prove that code behaves as expected.
- Test for both positive and negative use cases.
- Test triggers to process 200 records – make sure your code is “bulkified” for 200 records and doesn’t throw the dreaded “Too many SOQL queries” exception.
- When testing for governor limits, use Test.startTest and Test.stopTest and the Limit class
- Use System.runAs() to execute code as a specific user to test for sharing rules (but not CRUD or FLS permissions)
If i have missed something or anything is not appropriate then please tell me in comments.
Leave a comment