apex:actionFunction vs. Visualforce Remoting performance Tuning

Use JavaScript remoting in Visualforce to call methods in Apex controllers from JavaScript. Create pages with complex, dynamic behavior that isn’t possible with the standard Visualforce AJAX components.
JavaScript remoting has three parts:

  • The remote method invocation you add to the Visualforce page, written in JavaScript.
  • The remote method definition in your Apex controller class. This method definition is written in Apex, but there are few differences from normal action methods.
  • The response handler callback function you add to or include in your Visualforce page, written in JavaScript.

Example of using apex:actionFunction:

public with sharing class SearchforContactByName {

    public String customerLastName { get; set; }
    public List searchResults { get; private set; }

    public void searchforCustomerSearch() {
        customerLastName = '%' + customerLastName + '%';
        searchResults = [
            SELECT Id, FirstName, LastName 
            FROM Contact 
            WHERE LastName LIKE :customerLastName 
            ORDER BY LastName, FirstName 
            LIMIT 200
<apex:define name="body">
 <apex:form >  
  <apex:actionFunction name="findCustomerByName" action="{!searchforCustomerSearch}" reRender="customers"
  <apex:param name="customerLastName" assignTo="{!customerLastName}" value=""/>
  <input id="searchField" type="text" placeholder="Enter Last Name"/>
  <button type="button">Search</button>
  <apex:outputPanel layout="block" id="customers">
  <apex:dataTable value="{!searchResults}" var="sr">
  <apex:column >{!sr.LastName}, {!sr.FirstName}</apex:column>

Example below show how to use RemoteAction with Sencha Touch example:

Ext.define("ChatterPlus.model.Chatter", {
    extend: "Ext.data.Model",

    config: {
        idProperty: 'Id',

        fields: [
            { name: 'Id', type: 'string', persist: false},
            { name: 'Title', type: 'string'},
            { name: 'Body', type: 'string'},
            { name: 'LikeCount', type: 'string', persist: false},
            { name: 'CommentCount', type: 'string', persist: false},
            { name: 'Comment', type: 'string', persist: false},
            { name: 'Like', type: 'string', persist: false},
            { name: 'ParentId', type: 'string'}

        validations: [
             { type: 'presence', field: 'Title', message: 'Enter a Title' },
             { type: 'presence', field: 'Body', message: 'Enter a Body' } 

        //Bind each CRUD functions to a @RemoteAction method in the Apex controller
        proxy: {
            type: 'direct',
            api: {
                read:     ChatterController.Query,
                create:   ChatterController.Add,
                update:   ChatterController.Edit,
                destroy:  ChatterController.Destroy
            limitParam: 'recordCount',   // because "limit" is an Apex keyword
            sortParam: 'sortParams',     // because "sort" is a keyword too
            pageParam: false,            // we don't use this in the controller, so don't send it
            reader: {
                type: 'json',
                rootProperty: 'records',
                messageProperty: 'errorMessage'
            writer: {
                type: 'json',
                root: 'records',
                writeAllFields: false,   // otherwise empty fields will transmit as empty strings, instead of "null"/not present
                allowSingle: false,      // need to always be an array for code simplification
                encode:  false           // docs say "set this to false when using DirectProxy"



Remote Controller

    public static Response Add(List chatterData){
        return insertLeadList(chatterData);

    public static Response Destroy(List chatterData){
        return deleteChatterList(chatterData);

    public static Response Edit(List chatterData){
        return editChatterList(chatterData);

    public static Response EditComment(List chatterCommentData){
        return editCommentChatterList(chatterCommentData);

    public static Response Query(QueryRequest qr){

        Response resp = new Response();

        //Enforce a limit on the number of rows requested.
        final integer QUERY_LIMIT = 500;
        if( qr.start >= QUERY_LIMIT ){
            resp.success = false;
            resp.errorMessage = 'Maximum number of records (' + String.valueOf(QUERY_LIMIT) + ') exceeded!';
            return resp;

        try {
            getAllChatter(qr, resp);
        } catch (Exception e) {
            resp.success = false;
            resp.errorMessage = 'Query failed: ' + e.getMessage();

        return resp;

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s