logo

NJP

Reference field snRecordPicker: Performance Tips for ServicePortal/Angular Directive

Import · May 18, 2020 · article

The snRecordPicker directive is a very popular Angular directive to allow flexible reference field behavior in ServicePortal. There have been a couple really influential Community posts about how to use it:

https://community.servicenow.com/community?id=community%5Fblog&sys%5Fid=54bde6a9dbd0dbc01dcaf3231f96193f

https://community.servicenow.com/community?id=community_article&sys_id=762a09d5dbf8a700b2102926ca961...

I have noticed that while this functionality is very helpful it does not scale very well for performance. Here are some key tips to make your snRecordPicker implementation more performant:

You will need to make your own version of the directive as a ServicePortal widget. It is easier than you might think.

(Thanks Matt Glen for the tip!)

The below steps change the default search behavior to use a Startswith query (much more efficient for MySQL than the default Contains behavior) and also adds a 5 character minimum (configurable) before an auto-complete request will be sent.

1. Create a new "Angular Provider" of type "Directive" and name it in camel-case. (e.g. myRecordPicker, acmeRecordPicker, youGetTheIdea...)2. Copy paste the entire directive.snRecordPicker code from /scripts/js_includes_sp.jsx into the Client Script field of your new Angular Provider

3. Remove the below outer function call but keep everything else that is inside. With the minor exception of the function; which you must give a name so that "function(" becomes "function myRecordPicker("

angular.module('sn.common.controls').directive('snRecordPicker',
...keep everything in here...
)

4. Now make two minor changes:

- in the "scope" object (around lines 13-27) add a line as follows:

minimumInputLength: '=?',

- in the "config" object (around lines 94-98) add a line as follows (defaults to 3 if nothing set in HTML tag):

minimumInputLength: scope.minimumInputLength ? parseInt(scope.minimumInputLength, 10) : 3,

5. Add the new provider to your widget via the related list to "Angular Providers"6. In the template (sp_widget HTML Template field or sp_ng_template) where you used to reference "sn-record-picker" you replace that with "my-record-picker" (or the equivalent snake-case name, depending on the name you picked in step #1) - Angular will convert it to the equivalent camel case name you selected in step #1 automatically.

7. Add two new parameters inside the tag in your template, startswith="true" and minimum-input-length="5". It should end up looking something like this:

<my-record-picker
field="c.requestedForUserList"
default-query='c.data.requestedForFilter'
table="'sys_user'"
startswith="true",
minimum-input-length="5",
style="margin-top: 5px;"
display-field="'name'"
display-fields="'user_name,title'"
value-field="'sys_id'"
search-fields="'name,user_name,title'"
page-size="100"
multiple="true">
</my-record-picker>

8. As a final touch, in Orlando the Table REST API supports bypassing the COUNT(*) query. In the "search" method add "&sysparm_no_count=true" to the url as shown below:

var url = '/api/now/table/' + scope.table + '?' + urlTools.encodeURIParameters(queryParams.data) + "&sysparm_no_count=true";

See KB0817996 - Orlando Performance Improvement - Remove Pagination Count

While you're at it, ask your customer to consider raising the value of glide.xmlhttp.ac_wait_time to reduce the frequency of hitting the database with auto-complete requests. Bumping it up to 1000ms doesn't feel too bad, reduces back and forth network wait time and it saves a lot of processing on the database.

Labels:

image

View original source

https://www.servicenow.com/community/developer-articles/reference-field-snrecordpicker-performance-tips-for/ta-p/2330079