Performance consists of 7% of total score in Salesforce Platform Dev II Exam. The topic covers including performance issues, mitigation techniques, best practices, caching, and etc. particularly for Visualforce, Lightning Component, and SOQL and SOSL queries.

NOTE: This post is written in July 2019 and content might be changed/updated overtime. The content is inspired by focusonforce.com.

Visualforce Performance

  • Visualforce performance issues:

    • Long loading times due to large page size (Visualforce page max size: < 15MB)
    • Page stall and load slowly due to large View State size (170KB max, the smaller the quicker)
    • Concurrent Visualforce page request blocking other tasks
    • Insufficient queries that reduce page performance overall
    • Visualforce page may not display all data due to returned data size limit and batch limit
  • View State is used to preserve information about what is displayed on the page what data has been entered.

  • View State is stored as encrypted, hidden form field on Visualforce page.

  • It automatically handles all the details of state management during postbacks.

  • 'Development Mode' and 'Show View State in Development Mode' needs to be checked in Advanced User Details in order to view View State.
    show-view-state-in-development-mode

  • View State when previewing Visualforce page (page must have <apex:form> or HTML form):
    view-state-visualforce

  • Heap size is the amount of memory allocated to objects that are defined in Apex code.

  • Heap size for synchronous transaction is 6MB while 12MB for asynchronous transaction.

  • If heap size is over the limit, an error message will be displayed.

  • Visualforce best practices:

    • Optimize View State:
      • Use transient keyword in controllers for data that doesn't need for page refreshes to reduce view state size
        • Example: transient public final String accName {get; set;}
        • NOTE: it is recommended to avoid multiple input forms, but it has no bearing on view state size.
      • Use filters and pagination to reduce amount of data shown
      • number of forms on a page should be minimized by using <apex:actionRegion> component
      • only work-in-progress data should be stored in view state
      • Store read-only data in custom objects data or global values that is frequently used in custom settings
      • Non-action components such as <apex:outputLink> should be used instead of <apex:commandLink> or <apex:commandButton> to make the view stateless.
    • Reduce load times:
      • Cache frequently accessed data, such as icon graphics
      • Use pagination
      • Use lazy-loading Apex request to reduce request times (move heavy lifting duty to frontend, such as through Javascript Remoting, reRender attribute, custom components and etc.)
    • Handle concurrent requests:
      • Avoid resource-intensive operations (DML, webservice callouts and etc.) in action methods called by <apex:actionPoller>
      • Increase time interval for calling Apex from Visualforce
      • Move non-essential logic to asynchronous code block using Ajax
    • Reduce Heap Size:
      • Refactor code if heap size is approaching limit
      • Use Limits.getHeapSize() and Limits.getLimitHeapSize() to manage heap size during execution.
      • Use transient keyword in controllers
      • Do not store large amount of data in class variables
    • Other:
      • Specify with sharing keyword so that records accessible to the user are retrieved

Lightning Component Performance

  • Lightning Usage App can be used to view the user activity and usage.

    • Find out Monthly Active Users (compared to previous month) count and Daily Active Users (compared to previous day) count for Lightning Experience and Salesforce Mobile.
      active-users-count
    • Find out Monthly Active Users in last 3 months and Daily Active Users in last 30 days for Lightning Experience and Salesforce Mobile.
      active-users-month-date
    • Find out Weekly Active Users (7-day range) by Profile.
      active-users-profile
  • Lightning Usage App can be used to find out usage and performance by Browser and by Page.

    • Find out different browser usage count by month and by week.
      browser-usage
    • Find out different browser performance average page load time (ms) by month and by week
      browser-performance
    • Find out most viewed pages in last 7 days
      most-viewed-pages-last-7-days
    • Find out the performance of most viewed pages in last 7 days
      performance-most-viewed-pages-last-7-days
    • Find out the performance of single selected page in last 30 days
      performance-single-selected-page-last-30-days
  • page performance and activity by Browser, Page, Salesforce Mobile and etc. for past 30 days and 7 days depending on the matrix.

    • It displays the performance of Lightning pages in terms of page load times or Experienced Page Time (EPT), which is a measure of how long it takes for a page to load so that a user can meaningfully interact with it
    • 'Page' section displays the performance of top-viewed pages as well as single page performance. Page load times of a selected page are displayed for the previous 30 days.
    • 'Performance' pane displays page load times in both 'Browser' and 'Page' sections of the app.
  • Lightning Usage App can also be used to generate performance reports.
    lightning-usage-app

  • Lightning Component best practices:

    • Data Retrieval:
      • Use client-side technology for logic such as filtering and sorting
      • Limit number of rows and columns retrieved
      • Call to server should be made as last resort
    • Data Caching:
      • Cache data whenever possible
      • Caching is beneficial for high-latency, slow, and unreliable network
      • Use Storable Actions and Lightning Data Service to cache data on client-side
      • Use setStorable() method to store an action
var action = component.get('c.getItems');
action.setStorable();
action.setCallback(this, function(response){
    // handle response
});
$A.enqueueAction(action);
    • Cacheable Apex Methods
      • Apex class method can be annotated with @AuraEnabled(cacheable=true) to cache data returned from Apex method for component (API version 44 and above).
      • NOTE: no need to use setStorable() on Javascript action that calls Apex method
      • Caching allows quicker access to data without waiting for a server trip, data will be retrieved from server if the cached data is expired.
    • CDN
      • CDN (content delivery network) can be enabled to allow static files such as Javascript and CSS to cache versions in multiple geographic locations.
      • NOTE: though using CDN will speed up loading time, but it changes the source domain that serves the files which might be restricted by IPs (testing should be performed to ensure it works).
      • CDN can be enabled in Setup > Session Settings.
        session-settings-cdn
    • Component instantiation
      • Not all components need to be rendered
      • Host components in areas such as utility bar or global actions for lazy instantiation
    • Conditional Rendering
      • Use <aura:if> to conditionally display components
      • Toggle visibility of UI elements using CSS
    • Data binding
      • Use unbound expressions when possible since they don't maintain event listeners
      • Avoid large number of bound expressions
    • Events
      • Minimize number of event handlers by using unbound expressions, conditional rendering, component events for child-to-parent communication
    • List
      • Create finite number of list items when creating custom list components
      • Use pagination
    • Core Components
      • Use base Lightning Component whenever possible (those from Lightning namespace, such as <lightning:button>, <lightning:input>
    • Image Optimization
      • Use sprite-based Lightning Design System icons such as <lightning:icon>, <lightning:buttonIcon> instead of custom icons
      • Lock image dimension (otherwise image will be shown in distortion)
      • Use small image for small image usage, for example, don't use large image on thumbnail because it is really unnecessary
    • Rendering and Reflow
      • Avoid direct DOM manipulation
      • Lock DOM regions to specific dimensions to avoid browser reflows or surrounding areas
      • Minimize times needed to rerender components

Query Performance

  • Query performance issues:
    • Inefficient SOQL or SOSL queries
    • Things takes long to load or errors or timeouts
  • SOQL query best practices:
    • SOQL queries must be selective to ensure best performance

    • Terminate non-selective SOQL queries to avoid long execution times

    • Query on indexed field can reduce the resulting number of rows below system-defined threshold

      • Standard index field system defined threshold - 30% of first million records and 15% of records after that, up to 1 million records
        force.com-query-optimizer
      • Custom index field system defined threshold - 10% of first million records and 5% of records after that, up to 333,333 records
        force.com-query-optimizer-custom-index
    • Query to retrieve only the data required

  • Use Force.com Query Optimizer to optimize SOQL and SOSL queries.
  • It uses both statistics and pre-queries to generate the most optimized SQL to fetch data.
    • Checks each filter to determine which index should be used
    • Checks number of records targeted by the filter against selectivity threshold
  • Query Plan can be enabled via Developer Console > Help > Preferences.
    developer-console-preference
  • Query Plan can be used to evaluate the performance of a query.
    developer-console-query-plan
  • Query Plan will list the cost of query whether it will be doing TableScan or use an index anyway.
  • NOTE: queries should be written in a way that TableScan is not needed to perform
  • Fields that are indexed by default are:
    • Id
    • Name
    • OwnerId
    • CreatedDate
    • SystemModStamp
    • RecordType
    • External Id
    • Unique
    • Lookup relationship
    • Master-detail relaionship
  • Fields that are not indexed by default can be automatically indexed if Salesforce Query Optimizer recognizes that an index can improve performance for frequently run queries.
  • Customer can request Salesforce to add custom indexes on fields, but not all field types are allowed, such as multi-select picklist, currency field in multi-currency org, long text field, some formula field, and binary field.
  • NOTE: if an indexed custom field is empty or null, it will make the query non-selective.
  • NOTE: custom index will not be used if queried values exceed system-defined threshold, a negative operator (such as !=) is used in filter, or the filter compares with empty value (such as Name = '' or Name = null).
  • Further non-selective queries best practices:
    • SOQL queries should be designed with large data volume in mind
    • Hard delete option in Bulk API should be used to delete records that are not required permanently
    • Avoid using LIKE condition with wildcard '%' because it is not indexed
    • Avoid using comparison operator (such as >, <=) with text-based fields
    • Avoid using negative operator (such as !=) because it will prevent Force.com Query Optimizer from using index
    • Avoid using complex AND/OR conditions in a query, use separate queries instead
    • Avoid using non-deterministic formula fields because it doesn't support index
  • Using Sort can improve query performance as well:
    • Sort clause ORDER BY with LIMIT clause will force Force.com Query Optimizer to consider using index
    • Sort optimization is best when dealing with difficulty on adding filters to make a SOQL query selective.
    • For sorting, number or date data type fields are the best for sort optimization
    • NOTE: Force.com Query Optimizer will not consider using index if the sort clause is added on field that might contain null records
  • When writing SOSL queries, make sure it is as selective as possible. Ex: use 'Testing*' instead of 'Test*'
  • The scope of search should be limited by targeting specific objects.
  • Fields with search indexes in SOSL include:
    • Name
    • Phone
    • Text
    • Picklist

Well, that goes another chapter of revisioning. Have a wonderful one!

Post was published on , last updated on .

Like the content? Support the author by paypal.me!