The Now Platform® Washington DC release is live. Watch now!
on ‎10-18-2020 10:02 PM
Hi there,
One of the most common performance scripting mistakes I see on the ServiceNow Community and in customer Instances: the use of setValue() on reference fields/variables within Client-Side scripting. What mistake do I mean? Only providing a sys_id as a second parameter when using setValue().
Let's explain and what to do about this.
The third parameter
When using setValue() on a reference field, be sure to include the reference field displayValue as the third parameter. If you set the value without the displayValue, the ServiceNow instance does a synchronous call to retrieve the display value for the record you specified. This extra round trip to the server can impact performance.
So you might have set up a nice piece of Client-Side scripting, using getReference with a callback, using GlideAjax with getXML, or even better using GlideAjax with getXMLAnswer. Though if you fail to use the third parameter when using setValue(), your effort to perform an efficient lookup is actually wasted.
If you have a perfect performing instance, you will hardly notice the difference. You can just see this, happen though not enjoying enough. If you have a so so performing instance, a less internet connection, working on virtualization software, then this can become very painful.
The correct notation would be:
Incorrect example
Here an examples o incorrect applying setValue. Incorrect because it concerns a reference variable to sys_user, where they are only providing a second parameter with the sys_id:
g_form.setValue('manager',user.manager);
Additional synchronous call
So what additional synchronous call does the ServiceNow instance perform actually? For example using the Chrome DevTools (F12) in combination with the JavaScript Executor (CTRL+SHIFT+J), you could inspect the Network. Let's take the Incident form as an example, and set the Location reference field with only a second parameter.
Using:
g_form.setValue('location', '25ab9d720a0a0bb300793d3a6b891f82');
Results in:
Notice two requests have been performed. When having a closer look at the second request: the synchronous call which retrieves the display value.
<xml answer="6304 Northwest Barry Road, Kansas City,MO" sysparm_max="15" sysparm_name="getDisplay" sysparm_processor="AjaxClientHelper" sysparm_value="25ab9d720a0a0bb300793d3a6b891f82"/>
So an additional server call is executed, and the additional server call is also exectued synchronous! While you might just have tried to setup an efficient Client Side script using callback parameters, etcetera which theoretically is good or - when using GlideAjax with getXMLAnswer - even great. Though missing out on the third parameter… all your efforts to setup an efficient Client Side script just went down the drain! What a waste.
Providing third parameter, value AND displayValue
Let's execute the same, though now while providing a third parameter. A third parameter which represents the displayValue.
Using:
g_form.setValue('location', '25ab9d720a0a0bb300793d3a6b891f82', '6304 Northwest Barry Road, Kansas City,MO');
Results in:
Notice only one request has been performed. The additional synchronous server call mentioned in the previous step did not get executed this time!
Result
A small piece of knowledge, though a valuable one concerning performance. Try it yourself, and try to understand the difference. Again, this is one of the most made mistakes I see on the ServiceNow Community and on customer instance.
Just to mention again, the correct way:
---
And that's it actually. Hope you like it. If any questions or remarks, let me know!
If this post helped you in any way, I would appreciate it if you hit bookmark or mark it as helpful. Interested in more articles, blogs, videos, and Share projects on Performance I published? - Performance |
Kind regards,
Mark
2020 ServiceNow Community MVP
2020 ServiceNow Developer MVP
---
Thanks for the explanation,
Another great post
I have even seen MVP's contributing to solutions that don't take this into consideration - well worth pointing out. I've grown tired of pointing it out!
I wrote an API to wrap around GlideAjax for getting fields as an alternative to getReference() that takes this problem into consideration. Would love to get your thoughts on it and maybe even a code review!
ServiceNow Share - SmartAjax
Example
new SmartAjaxFieldMapper('caller_id')
.addFieldMapping('location','location') // Map value to location field
.getReference();
Just downloaded! Sounds really interesting, going to look into it next week.
Kind regards,
Mark
Hi,
I have 3 referenced fields in a knowledge article form.
1. Service
2. Support Group
3. Owned By
I want to populate data into fields 2 and 3 depending on what service is selected in field 1.
I am trying to achieve this by using client script. However I am get reference error while selecting a value in field 1.
Could anyone please help me on this?
Hi there,
Instead of replying to an article, consider posting a question for such on the Community. This will give you a bigger audience and a greater chance of replies.
Kind regards,
Mark