K-field calculation optimization tips
Follow these tips and best practices to optimize calculations in K-fields and improve backfill and cache-rebuild times:
-
Limit the number of K-fields — A backfill causes every K-field on every record to be recalculated. The fewer number of K-fields, the less time backfills take. And the program is simpler to manage.
-
Use Export Only K-fields as much as possible — Export Only fields are not calculated during backfills (because they are not in Slug).
-
Only add K-fields to Slug (choosing Available or Backfill Required) when you need to filter on them or add them to an aggregate report. By default, don’t add a K-field to Slug when you create it. You can always add it later if needed.
-
-
Limit the complexity — The fewer lines of code, the faster the calculation runs — keep them short!
- Avoid:
- Repeated calculations.
- Declaring and assigning variables at the beginning of the code (if at all).
- Using regex expressions as much as possible.
- Referencing other K-fields.
- Expensive functions, such as
getUnitDatafield()andgetUnitGroupFromOrgHierarchy().
See Programming idioms for JavaScript best practices, a reference of JavaScript functions in Medallia Experience Cloud, and for more tips about how to use the editor.
Use testing tools
Use the Testing tool option at the bottom of the K-field editor to identify any performance issues (status indicated in the lower-right panel after running a test).
The panel in the upper right shows which code-path is valid for the Survey ID. The line highlight colors indicate:
- Red is a condition that evaluated negatively.
- Green is a positive result.
- Gray lines were not executed.
The return result is shown and the Alternative Set value is highlighted (when applicable).
The editor is also useful for identifying syntax errors, as shown in this image:
Evaluate unused K-fields
Evaluate unused K-fields (with the Unused fields filter) and determine if the fields can be removed or at the very least, set to Export Only.
Wrap code in a function
This allows you to use return statements, which is standard JavaScript syntax. With return statements, the function stops executing once it finds the first true statement.
Consider this example that evaluates the else expression even when the if condition is true:
if (seqnum(e_survey_method) == 1) {1;}
else {null;}
Instead, enclose the entire condition in a function, like this to stop processing and return the result as soon as it is found:
(function () {
if (seqnum(e_survey_method) == 1) {return 1;}
else {return null;}
})();
Include comments
Make sure others can understand what you wrote (and don’t forget to fill in the K-fields Description property). Here’s how to comment in a K-field:
// This is a one line comment
// You should comment your k-field to explain what it’s doing
(function () {
if (seqnum(e_survey_method) == 1) {return 1;}
/* You can also comment like this
to comment across multiple lines */
else {return null;}
})();
Date/time values
Date and datetime K-fields only recalculate when:
- The survey record is updated.
- The K-field code itself is changed in a material way (modifying comments or whitespace does not count).
- A backfill is run.
- A deployment causes a cache rebuild.
Never reference the current date/time using now() or new Date() because the date value will change every time the record updates, such as after a backfill or cache rebuild.
For example, consider a K-field that calculates the age of the customer. This K-field might look like the following:
(function () {
var a = e_companyname_cust_birth_date;
if (a == null) {
return null;
}
var birth = date(a);
var today = date(now()); // *** Bad: Do not do this
var years = new org.joda.time.Period(birth, today);
return years.getYears();
})();
The example above calculates the age of the customer when the survey is first loaded, and each time the record updates, which over time will not reflect the customer's age when the record was completed.
Instead, use a static survey date field such as e_creationdate instead of now():
var birth = date(a);
var today = date(e_creationdate);
var years = new org.joda.time.Period(birth, today);
return years.getYears();
Minimize JavaScript
The more complex the JavaScript code, the longer it takes to calculate when running backfills and cache rebuilds.
Optimize multiple if statements
If you must compare multiple scenarios, it is often best to nest conditional statements. Consider this example that tests multiple scenarios:
If (a==1 && b==2) { // do v // };
If (a==1 && b==3) { // do w // };
If (a==1 && b==4) { // do x // };
If (a==2 && b==2) { // do y // };
If (a==2 && b==3) { // do z // };
Here is a much better approach:
if (a==1)
{
if (b==2) { // do v // }
else if (b==3) { // do w // }
else if (b==4) { // do x // }
}
else if (a==2)
{
if (b==2) { // do y // }
else if (b==3) { // do z // }
}
The second approach is better because first approach always executes 5 lines code, regardless of the values of a and b. So, when a=2 and b=3, the first example executes every line until it gets to the last line. In the second example, most of the first block of code is completely skipped and never executed.
This may seem like a small improvement, but it will be compounded over millions of records during a backfill, significantly reducing the calculation time.
Avoid defining unnecessary variables
When a variable is used only once, just use the expression/assignment inline where needed.
Bad:
b = seqnum(q_b);
c = seqnum(q_c);
if (a == 1) {
return 1;
} else if (b == 1) {
return 2;
} else if (c == 1) {
return 3;
}
Good:
if (seqnum(q_a) == 1) {
return 1;
} else if (seqnum(q_b) == 1) {
return 2;
} else if (seqnum(q_c) == 1) {
return 3;
}
Avoid repeatedly calling functions
Instead, save the value to a variable if it is used multiple times.
Bad:
if (getUnitDatafield(e_unitid, 'capone_alert_new_promoter_email') == null || getUnitDatafield(e_unitid, 'capone_alert_new_promoter_email') == “fly”) {
return getUnitDatafield(e_unitid, 'capone_alert_new_promoter_email') + “ the seventh sky”;
}
if (getUnitDatafield(e_unitid, 'capone_alert_new_promoter_email') == “walk”) {
return getUnitDatafield(e_unitid, 'capone_alert_new_promoter_email') + “ the face of the moon”;
}
return getUnitDatafield(e_unitid, 'capone_alert_new_promoter_email') + “ something”;
Good:
email = getUnitDatafield(e_unitid, 'capone_alert_new_promoter_email');
if (email == null || email == “fly”) {
return email + “the seventh sky”;
} else if (email == “walk”) {
return email + “ the face of the moon”;
} else {
return email + “ something”;
}
Use meaningful variable names
Nonsense variable names are hard to read and debug when used in large code. The code should sound like English as much as possible when you read it.
Bad:
i = e_unitid;
a = seqnum(k_medallia_flyer);
b = seqnum(q_medallia_bad_dude);
if(a == 6 && b == 3) {
c = 1;
} else {
c = 2;
}
if (i == 332 || c == 1 || a == 2) {
return 1;
} else {
return 2;
}
Good:
flyer_num = seq(k_medallia_flyer);
bad_dude_num = seqnum(q_medallia_bad_dude);
is_third_flyer =
(flyer_num == 6 && bad_dude_num == 3) ? 1 : 2;
if (e_unitid == 332 || is_third_flyer == 1 || flyer_num == 2) {
return 1;
} else {
return 2;
}
