From the KB - @UserRoles and caching - I didn't know this...
@UserRoles Generates Network Traffic and Slow Client Response Time
You find that the response time for documents created with particular form that uses @UserRoles in Hide When formulas is very slow when creating, refreshing, or saving the documents. In your debugging, you see that there is a lot of network traffic occurring. Is @UserRoles creating this overhead? Why isn't it also slow when opening existing documents? Can the network traffic be reduced and performance improved?
This Technote will describe four things about @UserRoles:
- How does the UserRoles @function work in R5?
- Why does @UserRoles generate network traffic in Hide When formulas but not field formulas?
- Why do multiple Hide When formulas containing @UserRoles perform better on some forms than others?
- What is the recommended design when using @UserRoles in Hide When formulas?
How does @UserRoles work in R5?
@UserRoles does not cache on the client. This means that whenever @UserRoles is evaluated, it does need to make Notes Remote Procedure Calls (RPC) to access the database Access Control List (ACL) on the server to retrieve the names list. This is similar to using @DbColumn or @DbLookup with the "NoCache" parameter. Unfortunately, @UserRoles does not have an option to specify whether to cache or not to cache. The database designer needs to take this into consideration and make judicious use of the @UserRoles function since it does make RPC calls to evaluate.
Why does @UserRoles generate network traffic in Hide When formulas but not field formulas?
If you have @UserRoles in field formulas for Computed fields, the fields are, by definition, evaluated only when a document is created, refreshed, or saved. You will notice that performance is fine when opening existing documents because the computed fields are not evaluated; hence, you will not experience the network traffic related to evaluating @UserRoles. You will see slower performance when composing these same documents with @UserRoles in the field formula, because you will have the network traffic associated with @UserRoles evaluation. Hide When formulas, on the other hand, are evaluated for new as well as existing documents to correctly hide elements of the document in either mode.
Why do multiple Hide When formulas containing @UserRoles perform slower on some forms than others?
While @UserRoles is not cached, during a form refresh, identical Hide When formula are executed only once. The evaluated result is then used in every place that the identical Hide When exists on the form. So, while different forms may have the same number of @UserRoles function calls, those forms with multiple different Hide When formulas will be "slower" than forms with multiple identical Hide When formulas.
For instance, create a form that has five fields where each field has a Hide When formula using @UserRoles once. If each field has a different Hide When formula that uses @UserRoles, Notes will access the server five times, once for each Hide When containing @UserRoles in the formula. If instead of five different formulas, there is only one Hide When formula with @UserRoles that applies to all five fields, Notes will access the server only once. It doesn't matter how you apply the Hide When formula to the design elements. You may apply the Hide When formulas to individual fields or instead highlight all of the design elements and set the Hide When formula all at once. Still, the Hide When is only evaluated once if it is the same Hide When formula. This is the case whether the five fields are in the same paragraph or separated by other fields without Hide When formulas or with different Hide When formula.
What is the recommended design when using @UserRoles in Hide When formulas?
The best way to resolve the performance issues related to @UserRoles is to improve the design of the forms by eliminating redundant @UserRoles. Instead of using @UserRoles many times on the same form, evaluate @UserRoles once in a hidden 'Computed for Display' field. Then refer to this field when roles membership is required. At the very least, use a temporary variable set to @UserRoles once per formula to eliminate multiple @UserRoles calls within the same formula.
For example, suppose you have a Hide When formula that uses @UserRoles five times to determine membership in five different roles as follows:
@IsMember("[Role1]";@UserRoles) | @IsMember("[Role2]";@UserRoles) |
@IsMember("[Role3]";@UserRoles) | @IsMember("[Role4]";@UserRoles) |
Instead of this method, create a 'Computed for Display' field named UserRoles at the top of the form. Make the formula for this field simply:
Then, all Hide When formulas that depend on @UserRoles can reference that field:
@IsMember("[Role1]";UserRoles) | @IsMember("[Role2]";UserRoles) |
@IsMember("[Role3]";UserRoles) | @IsMember("[Role4]";UserRoles) |
Note that all calls to @UserRoles in the first Hide When formula have been replaced by references to the new field, UserRoles. This reduces the formula to only one @UserRoles network transaction per refresh.