Run only necessary client scripts

This article is based on the ServiceNow documentation article. See the original article on the ServiceNow doc site: Run Only Necessary Client Scripts

Client Scripts have no Condition field. This means onLoad() and onChange() scripts run in their entirety every time the appropriate form is loaded. To avoid running time-consuming scripts unnecessarily, make sure Client Scripts perform only necessary tasks.

This example is an inefficient onChange() Client Script set to run when the Configuration item field changes.

//Set Assignment Group to CI's support group if assignment group is empty
function onChange(control, oldValue, newValue, isLoading) {
 
    var ciSupportGroup = g_form.getReference('cmdb_ci').support_group;
	
    if (ciSupportGroup != '' && g_form.getValue('assignment_group') != '')
        g_form.setValue('assignment_group', ciRec.support_group.sys_id);
}

The following steps provide examples showing how this example can be improved to prevent the Client Script from running unnecessary code.

General Cleanup

Look for performance optimizations. In the previous example, the getReference(), or GlideRecord lookup can be replaced with an asynchronous GlideAjax call.

//Set Assignment Group to support group if assignment group is empty
function onChange(control, oldValue, newValue, isLoading) {

    var ga = new GlideAjax('ciCheck');

    ga.addParam('sysparm_name', 'getSupportGroup');
    ga.addParam('sysparm_ci', g_form.getValue('cmdb_ci'));
    ga.getXML(setAssignmentGroup);
}

function setAssignmentGroup(response) {

    var answer = response.responseXML.documentElement.getAttribute("answer");

    g_form.setValue('assignment_group', answer);
}

Keep the isLoading Check (onChange Client Scripts Only)

The isLoading flag is the simplest way to prevent unnecessary code from taking up browser time. The isLoading flag should be used at the beginning of any script which is not required to run when the form is loading. There is no need to run this script on a form load because the logic would have already run when the field was last changed. Adding the isLoading check to the script prevents it from doing a cmdb_ci lookup on every form load.

//Set Assignment Group to CI's support group if assignment group is empty
	function onChange(control, oldValue, newValue, isLoading, isTemplate) {
	
	    if (isLoading)
	        return;
	
	    var ga = new GlideAjax('ciCheck');
	
	    ga.addParam('sysparm_name', 'getSupportGroup');
	    ga.addParam('sysparm_ci', g_form.getValue('cmdb_ci'));
	    ga.getXML(setAssignmentGroup);
	}
	
	function setAssignmentGroup(response) {
	
	    var answer = response.responseXML.documentElement.getAttribute("answer");
	
	    g_form.setValue('assignment_group', answer);
	}

If the onChange script should run during form load, use the following convention:

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
 
    if (isLoading) {}; // run during loading
 
    // rest of script here
 
}

Keep the newValue Check

The newValue check tells this script to continue only if there is a valid value in the relevant field. This prevents the script from running when the field value is removed or blanked out. This also ensures that there will always be a valid value available when the rest of the script runs.

//Set Assignment Group to CI's support group if assignment group is empty
function onChange(control, oldValue, newValue, isLoading, isTemplate) {

    if (isLoading)
        return;

    if (newValue) {
        var ga = new GlideAjax('ciCheck');

        ga.addParam('sysparm_name', 'getSupportGroup');
        ga.addParam('sysparm_ci', g_form.getValue('cmdb_ci'));
        ga.getXML(setAssignmentGroup);
    }
}

function setAssignmentGroup(response) {

   var answer = response.responseXML.documentElement.getAttribute("answer");

   g_form.setValue('assignment_group', answer);
}

Add the newValue != oldValue Check

To have the script react to a value which changes after the form loads, use the newValue != oldValue check.

//Set Assignment Group to CI's support group if assignment group is empty
function onChange(control, oldValue, newValue, isLoading, isTemplate) {

    if (isLoading)
        return;

    if (newValue) {
        if (newValue != oldValue) {
            var ga = new GlideAjax('ciCheck');

            ga.addParam('sysparm_name', 'getSupportGroup');
            ga.addParam('sysparm_ci', g_form.getValue('cmdb_ci'));
            ga.getXML(setAssignmentGroup);
        }
    }
}

function setAssignmentGroup(response) {

   var answer = response.responseXML.documentElement.getAttribute("answer");

   g_form.setValue('assignment_group', answer);
}

Bury the GlideAjax Call

In this example, the GlideAjax call is buried one level deeper by rearranging the script to check as many things available to the client as possible before running the server calls. The script checks the assignment before executing the GlideAjax call. This prevents the server lookup when the assignment_group field is already set.

//Set Assignment Group to CI's support group if assignment group is empty
function onChange(control, oldValue, newValue, isLoading, isTemplate) {

    if (isLoading)
       return;

    if (newValue) {
        if (newValue != oldValue) {
            if (g_form.getValue('assignment_group') == '') {
                var ga = new GlideAjax('ciCheck');

                ga.addParam('sysparm_name', 'getSupportGroup');
                ga.addParam('sysparm_ci', g_form.getValue('cmdb_ci'));
                ga.getXML(setAssignmentGroup);
            }
        }
    }
}

function setAssignmentGroup(response) {

   var answer = response.responseXML.documentElement.getAttribute("answer");

   g_form.setValue('assignment_group', answer);
 }