I enjoyed attending MAX last week. The best part was putting some faces to names of people who had previously been cyber-personalities.
We did a pre-conference lab on LiveCycle best practices. For the lab I prepared four exercises on various aspects of form design. For those who weren’t able to attend, I’ll post those exercises as a series of blog entries.
Exercise #1: Measure and Improve JavaScript Performance
In this exercise we optimized a fairly simple script – a few lines in a loop. Depending on your machine, you should be able to improve the performance anywhere from a factor of three up to a factor of seven.
Open EX1 Performance Tests.pdf in Designer.
There are 50 subtotal values that need to be totaled. Each total has a test button that executes the Total script 500 times and measures the performance.
Note the 4 variations of the sum function:
- Test 1: The original (slow) version of the calculation
- Test 2: A copy of Test 1 that you will improve.
Look at the hints in the code comments in order to improve the script. - Test 3: The solution
- Test4: Same calculation expressed in FormCalc
Understanding the solution:
- Undeclared variables are very expensive to reference
- Javascript variables are far less expensive to reference than XFA objects
- Evaluate as few dots as possible. e.g. c.d is faster than a.b.c.d
- Dots evaluated inside a resolveNode(s) expression are faster than dots evaluated in JavaScript objects. E.g. resolveNode("a.b.c") is faster than a.b.c
Why is FormCalc faster?
All references to XFA objects from JavaScript involve a round-trip from the script environment to the XFA processor and back. These round trips are expensive.
FormCalc runs native in the XFA processor and there are no round-tripping costs.

You can speed version 3 up a bit more if your willing to do a bit of house keeping elsewhere that allows you to remove the resolveNodes call. I did a version that supposed the repeating group was static. I declared an array variable within the testRunner script block and in the initialize event on the subtotal field I had the fields push themselves into this array. Then in the calculate I simply retreived this array and looped over it. In the end my times worked out as follows.
test 1 – 3.37
test 2 – 0.59 My optimized version
test 3 – 1.44
test 4 – 0.39
Still doesn’t quite match FormCalc but pretty close.
Keith:
You’re absolutely right. Yes, there would be extra housekeeping, but clearly lots of pay-back for your effort. I like it.
John
// Sticking to the original problem
var rows = Rows.resolveNodes(“Row[*].subtotal”); // 10% boost
c:
that improvement makes sense one less dot to process
John