Created 12/12 11:13 AM Modified 10/22 10:36 AM
This document explores
Two approaches for identifying application performance problems are:
1.1 Monitoring Resource Limitations-- "Where does it hurt?"
Performance of a Domino application on the server is always bound by one or more of the following factors:
When simulating user load, look into using a tool like Domino Server.Load, which started shipping with Domino 4.6.3. Domino Server.Load allows you to run a script (a simulated workload) in your own environment to obtain server capacity and response metrics. It can help evaluate the requirements for additional CPU, memory, or disk storage upgrades.
Later, after you've increased application performance using the techniques in this document, a point will be reached where a different factor is now limiting the performance. At that point, reassess and re-tune the environment if performance is still not acceptable.
1.2 Determining the Problem
Once you've identified some limiting factors of performance, you don't really know the problem. The following table shows where to focus attention in a Domino application depending on which factor is limiting application performance. The improvement potential column is only a subjective rating based on experiences of the author.
|Limiting Resource||Area of focus||Improvement Potential|
* = little
* * * * = significant
|Disk access||Optimize view designs|
Optimize code implementation
Optimize server .INI file cache settings*
Take advantage of browser caching
Upgrade to faster drives*
|* * * *|
* * * *
* * *
|Processor||Upgrade CPU (on server and on workstation)|
Optimize code implementation
Optimize server .INI file processor and agent settings*
Disable server screen saver*
Take advantage of browser caching
|* * * *|
* * * *
* * *
|Memory||Increase server RAM*|
Optimize server .INI file memory settings*
|* * * *|
* * *
|Network||Increase network capacity*|
Convert Notes client apps to Domino web apps
Take advantage of browser caching
|* * * *|
* * *
* * *
The right column indicates the subjective rating for improvement potential. Some of these areas of focus are detailed in the following sections in this document. All of these improvements should be considered, and caveats are mentioned where applicable.
1.3 Analyzing Performance by Debugging
If your application's performance problems are due to slow running LotusScript routines, you can find out exactly where by turning on the LotusScript debugger (File...Tools...Debug LotusScript). For large scripts, or scripts with long loops, place breakpoints around suspected problematic code blocks and note the delay when stepping through each these blocks. You'll soon discover at least one block where your delay is occuring. Place more breakpoints within the suspect block, and try to isolate the particular loops or lines of code that are causing delay. In particular, take note of any single line of code that incurs a noticeable delay when stepping line by line. For example, getView() frequently takes on the order of one second, which is painfully slow if you use it in a long loop.
1.3.1 Debugging LotusScript in Scheduled Agents and Dialog Boxes
Debugging LotusScript that is in a scheduled agent or a dialog box is a bit more complex, because the debugger cannot be used in those scenarios. For scheduled agents, temporarily set "When should this agent run?" to "Manually From the Actions Menu" and set "Which document(s) should it act on" to "Selected Documents". Then select in a view the target document(s) upon which this agent should act. Run the agent from the Actions menu while the LotusScript debugger is turned on.
1.3.2 Debugging Web Query LotusScript and Java Agents
To debug LotusScript WebQueryOpen and WebQuerySave agents, simply make sure that the agent type is set to "Manually From the Actions Menu". Open the target document in Notes, and then run the agent from the Actions menu. The NotesSession.DocumentContext property will reference the target document without any changes to your agent's code, and you'll be able to use the LotusScript debugger. CGI variable fields, however, won't evaluate as they would on the web. To work around this, you can modify the values of these variables manually in the long editable field at the bottom of the debugger while stepping through code.
For debugging Notes Java agents in your Java development environment, see Bob Balaban's March 1998 article on www.Notes.Net Debugging Java Agents.
1.3.3 Debugging Agents on the Server
Sometimes your agent will only run on the server, or the performance problem might only exist when it runs on the server. If you want to measure the performance of your agent as it runs on the server, try writing to agent logs. Each agent has an associated log that is accessible through the menu command Agent\Log... when the agent is selected in the agent design list. To use this feature for tracking performance, add code at the beginning of your script to open an agent log. Use the LogAction method throughout your code using the same logic as when setting breakpoints using the debugger.
Call agentLog.LogAction("Break 1")
'...suspected slow code
Call agentLog.LogAction("Break 2")
1.4 Watching Remote Procedure Calls (RPC's)
On Notes 4.5 and higher for Windows 95, you can take advantage of an undocumented feature of the Notes client to debug performance. Add the following entries in your NOTES.INI file (only try this on Windows 95/98):
|Open_Session||Authenticate with the server and establish a session|
|Open_Database||Find and open a database|
|Open_Note||Send the contents of a note (data document or design element)|
|Open_Collection||Open a view|
|Read_Entries||Send a list of information from a view or search, usually follows Open_Collection|
|Find_By_Key||A view lookup via DBLookup|
|Get_Special_Note_ID||Send info from the ACL|
|Close_dB||Close DB session|
1.5 Determining the Problem
From debugging and RPC analysis, you'll have some ideas as to what specific actions in Notes are impeding the performance of your Notes application. The following table presents some common reasons for various symptoms of poor performance.
|Performance symptom||Possible problem|
|Opening a view||
|Creating/opening a document||
|Saving a document||
|Creating/opening/saving document via web browser||
2. Improving Application Performance
This section includes several performance improvement techniques in the areas of views, code, forms, tables, fields, caching, security, and database size.
2.1 View cleanup and index settings
Frequently, the view indexing process on a server is overloaded due to database design characteristics. Consider that every time a document is saved, Domino refreshes the index for any view selecting that document. Large, all-selecting views, particularly those with time functions and multiple categorization, can decrease server-to-user response time significantly. Long delays (> 5 seconds) when saving a document whose form triggers no particularly complex validation or QuerySave event logic is frequently the result of excessive disk activity on the server. This disk activity in a large Domino application is caused by many views being updated as a result of the document update, and is magnified when multiple users save documents frequently. A large all-selecting view with a time function in a categorized column has been shown to cause document save response time to increase ten-fold on a view of only 400 documents.
2.1.1 View Maintenance
Eliminate unused, redundant or duplicate views. A design analyzer tool is useful for locating references to views and other design elements. Specifically, try to minimize the total number of view-documents that are re-indexed whenever a document is saved. To do this, implement several small views that can replace the need for one large view. A good example of this technique is to break down an aggregate view into 26 views, according to the first letter, A through Z. This provides more efficient view index refreshing than one all-inclusive view. This is because one of 26 small views will be re-indexed each time a document is saved, much faster to index than a single large view.
Minimize the number of views. During design, you may have created a new view for each lookup or LotusScript routine that uses a view. That may be the most easily maintainable model, but those extra views can cost a lot of performance. Combine columns from any hidden views that have identical selection formulas. A design analysis tool can help to quickly scan selection formulas. Extend this technique to include even the visible user views if you don't foresee them changing much. Note, however, if a new column needs to be added it is likely that all column numbers referenced against that view will need to be updated throughout your code. So this technique is only recommended as a last resort to improve performance.
2.1.2 View Design
Tailoring views is a great, fundamental tool in Notes. There are costs to each feature, however. Use these suggestions to help you make decisions about what kinds of views to make.
Remove any occurrences of @Now and @Today in view column formulas. Often, developers attempt to use @Today in a view column to measure elapsed days, or aging, of documents in approval processes. In some cases, when such a column is removed, the time to open the view from a web browser was reduced by 70%. To add this functionality in a more efficient manner, replace the time-based column formula with a reference to a new field, say ElapsedDays. Then run an agent on a nightly schedule that updates ElapsedDays based on @Today. A disadvantage of this technique is that all documents will be modified, causing excessive replication activity.
In fact, where feasible, all formulas in view columns should be migrated to new computed fields on forms. These fields can then be directly referenced in view columns for optimal view performance. This is usually best implemented after the application design is somewhat finalized, so that during development you can still change formulas easily without having to run data conversion macros.
Sorted columns take longer to index than non-sorted columns, and categorized columns longer still. If a view has no sorted / categorized columns, and the design is changed so that there is now one such column, there will be a noticeable slowdown in indexing time. If a second column is turned into a sorted / categorized column, there will be an additional slowdown, less severe than the first slowdown, but still noticeable. Each additional sorted / categorized column will add to the indexing time, but each slowdown will be less severe than the previous one.
There is a direct relationship between the number of columns and the number of documents, to the size of the view index. Index size, however, generally does not cause degradation in performance.
Documents appearing in multiple categories increase the size of the view index and the time to refresh it considerably.
The more information contained in SUMMARY fields, the larger the view index. The only way to remove this flag is via the LotusScript isSummary property of the NotesItem class.
2.13 View Placement
It is possible to split a database onto multiple servers, and have different views on the different servers. For instance, the read-only views could be on a Statistics, Printing, Searching, Managers' replica of the database. The Working views could be on the users' replica of the database. The two replicas would see each other as Editors only, so that they would not trade view design.
The Working Users' Database would constantly be updating because of user traffic. However, with the Managers' views taken out, there would be far less updating to be done. Furthermore, the Managers aren't even accessing this copy of the database, so that eliminates that group of users for authentication purposes.
The Managers' Database would only update after replication. You can set these two replicating servers up so that the replicator on the Users' Server is never used. The replicator on the Managers Server can do all the work. The Managers Server probably has a much smaller base of users to authenticate, and its indexer only needs to run after the replication cycle (every couple of hours, probably).
Views can also be made Shared, Private on First Use or Private. These view indices will be stored on the server if the user has the database ACL privelege "Create Personal Views", otherwise such views are stored locally on the users' desktop.dsk files. To remove the burden of indexing personal views on the server, either disable the "Create Personal Views" privelege or check the view design checkbox to "Store in Desktop". Also, depending upon the size of the view index, the users may find that their desktop.dsk files grow alarmingly!
2.2 Optimize code implementation
In general, move any application processing to the most server-efficient feasible point of implementation. For a Domino web application, points of implementation in order of decreasing server processing efficiency are shown in the table below:
|Point of Implementation|
Point of Execution
|2. Formulas (computed for display fields)|
Server (Notes core)
|3. LotusScript/Java scheduled agents|
Server (Agent process)
|4. LotusScript/Java triggered agents (WebQueryOpen, WebQuerySave)||
2) Use Formula fields where possible instead of LotusScript/Java agents.
3) Use scheduled agents to perform periodic batch processing on any documents that do not need to be immediately updated. This may be applicable for mail notification, data exporting to an outside application, or other scenarios where it is too costly to perform such functionality in real-time. Minimize the number of times the agent process is started, not just the amount of total work the agent must perform.
The following code provides a button that only submits the form if the Amount field is not empty, otherwise it prompts the user to fill in the field with a pop up dialog followed by automatically placing the cursor in the Amount field.
In cases where you can use either a LotusScript or Formula implementation, there are many factors that govern which will perform better. These factors are explained below.
2.4.1 WebQueryOpen and WebQuerySave Events (web only)
On the Notes client, the user's workstation bears the load of executing LotusScript form events. However, the WebQueryOpen and WebQuerySave events run on the Domino server. Multiple web users opening and saving documents using forms containing WebQueryOpen and WebQuerySave events causes a lot of processing on the server. In these cases, Formula language agents are generally much faster than LotusScript agents. This is because
|View: ItemScheduleLookup, third column formula|
|sep := "!~@";|
@Text(@DocumentUniqueID) + sep + @Text(ItemDeliveryDate) + sep + @Text(ItemDeliveryQuantity)
|Field name: Schedule_Display, type: computed for display, text|
| REM "only update if the doc is being loaded";|
@If(@isDocBeingLoaded; Schedule_Display; @Return(""));
REM "get status of parent req, and write to this LineItem";
parentStatus := @DbLookup("":"NoCache"; ""; "RequisitionNumberLookup"; ReqNbr_1; [statusColumnNumberGoesHere] );
FIELD ItemDocStatus := parentStatus;
REM "build an HTML table of child Schedule documents with a single lookup to optimize performance";
tableRowData := @DbLookup("":"NoCache"; ""; "ItemScheduleLookup"; ReqNbr_1 + LineItemNumber; 3);
@If(@isError(tableRowData); @Return(""); "");
REM "parse out results of the single lookup into three columns, using the same separator as defined in the view column";
sep := "~!@";
var_unid := @Word(tableRowData; sep; 1);
var_date := @Word(tableRowData; sep; 2);
var_quantity := @Word(tableRowData; sep; 3);
tablestringHead := "[" + "<TABLE BORDER=0 WIDTH=300 ALIGN=CENTER><TR><TH>Delivery Date<TH>Quantity<TR>";
REM "splice the three columns from above into the HTML for table rows";
tablestringBody := "<a href=\"/" + HomePage + "/By+DocUniqueID/" + var_unid + "?EditDocument\"><TD ALIGN=CENTER>" + var_date + "</a><TD ALIGN=RIGHT>"+ var_quantity + "<TR>";
tablestringHead + tablestringBody + "</TABLE>]"
2.5.1 @Db Functions
@DbLookups and @DbColumns are incredibly useful, but they can be quite a performance drag on a large application. Use these rules of thumb to minimize the cost of your @Db functions, without reducing functionality.
Controlling when intense computations occur can significantly improve domino processing time. For example, use Computed when Composed for any formulas that only need to be executed upon creation of a document.
Another means to minimize the execution of redundant lookups of any data field D dependent on field A is to restrict the lookup formula from executing if field A has not changed since the last time the lookup performed. To do this, add a field old_A before field A which traps the previous value of A. Also add a computed for display number field is_A_Being_Changed before the field old_A, with formula (A != old_A). In the lookup formula for D, only perform the lookup @IF(is_A_Being_Changed; @DbLookup(...); D). If the field A has not changed, the existing value for D will be retained.
2.6 LotusScript Performance Tips
These LotusScript performance tips are excerpts from from the Lotus Notes Knowledgbase and the Lotus Notes 4.6 Best Practice Guide.
2.6.1 GetView method
Streamline your use of the GetView() method. This method is particularly costly from a performance standpoint. Consider declaring view objects and other frequently used objects at the module level (database, form, or view declarations section). This allows such objects to be accessible from other scripts within the module, reducing the need to re-assign their values.
2.6.2 Autoreload property
Suppose you're using both the NotesUIDocument and NotesDocument classes in a form or subform. When AutoReload is enabled (it is enabled by default), every time you change a value on the back end document (using the NotesDocument class), field data is reloaded into the user interface. To improve performance, before your script does any updates use the following statement to disable AutoReload:
Assigning explicit variable types results in faster code than assigning variant as the generic type. This is particularly true when performing integer operations, where an iteration with integer declared can perform up to 200 percent faster than the same operation with variant declared. The difference is less dramatic with string operations.
2.6.4 GetNthDocument vs GetNextDocument
Looping through a NotesView or NotesDocumentCollection using GetNthDocument results in increasingly sluggish performance as the loop progresses. The decreased performance will occur if you use GetNthDocument to loop through a large NotesDocumentCollection or NotesView. Using GetFirstDocument and GetNextDocument, instead, will result in improved performance. Two sample scripts from the Lotus Notes Knowledgebase are illustrated below. The second script (using GetFirstDocument and GetNextDocument) will complete more quickly than the first script (using GetNthDocument).
In the following example, the first fragment runs 60 percent faster than the second fragment.
For y=1 to 15000
Loop While y<= 15000
2.6.6 Avoid using arrays to store intermediate results
Storing data in arrays rather than in non-array variables can degrade performance up to 50 percent. If possible, avoid using arrays to store intermediate results. In the following examples, code fragment A runs twice as fast as code fragment B.
for i=1 to 100
sum = sum + x(i)
for i=1 to 100
2.6.7 Searching an array for a string element
To find out if a string is a member of an array:
1. Create a single string of all the strings in the array.
2. Use INSTR.
3. Bracket each string in the array with a delimiter -- for example, a carriage return.
This search technique does not work if the resulting string is more than 32K.
2.6.8 Indexing arrays
Index the first bound of an n-dimensional array with the innermost loop, and index the last bound with the outermost loop. In the following examples, code fragment A runs 400 percent faster than code fragment B.
for y=0 to 2
for q=0 to 5000
for q=0 to 5000
for y=0 to 2
2.6.9 Tips for using strings
Avoid overusing copy and append operations. For example, the operation x$=x$+"a" is expensive in terms of performance.
If you know the size of a string in advance, pre-initialize the string.
Because comparing strings is slower than comparing integers, use an integer operation where possible.
In the following examples, code fragment A is 50 percent faster than code fragment B.
If (Asc(x$) = Asc("A"))
If (Left$ (x$, 1) = "A")
If (Asc(Mid$ (x$, 1, 1) = "A"))
If(Mid$(x, 1, 1)= "A")
If (Len (x$) = 0)
If (x$ = "")
2.6.11 Simplify if statements
This statement always results in both conditions being evaluated.
2.6.12 Miscellaneous LotusScript Performance Tips
Large tables, particularly those with editable fields, are known performance killers when rendering documents through a Notes or web client. For large static tables, try aligning data using a tab-formatted area of the form instead of using an actual Notes table. Or, if you really want to keep a large Notes table, minimize the size of the largest table by breaking it down into multiple smaller tables. Five 10 x 10 (row x column) tables load about twice as fast as one 50 x 10 table. You can hide the whitespace between multiple smaller tables and they will appear as one continuous table.
2.7.1 Computed subforms
A technique that works well for forms that require dynamic tables (such as timesheets, purchase requisitions, etc.) is to insert a subform based on a formula. Say a timesheet should support time capture for up to 20 projects, one per table row, on a single form. A computed when composed field called TimeTableSubform should include the text formula "Subform10". Insert a subform based on a formula, and set that formula to TimeTableSubform so that it references the value in the computed when composed field. Create a subform for the 20 row version of the table ("Subform20"), then one for the 10 row version ("Subform10"). Implement an action bar button that increases the number of line item rows from 10 to 20, by setting the TimeTableSubform value to "Subform20", and then executing a script or formula to re-open the document, such as @Command([ViewSwitchForm]; form) (not an available command for new documents until they are saved and reopened), the LotusScript NotesUIWorkspace.EditDocument() method in R4.5 and later, or @Command([OpenDocument]; unid). In Notes versions prior to 4.64, the ViewSwitchForm command may open the wrong document if the document's position in the view has changed since it was opened. For 10 rows, this is a faster performing form to load than one that always includes the 20 row version of the table with hide-when formulas to suppress the unused rows.
Another technique for dynamic tables is to allow the user to add/edit/remove table data through a Dialog Box user interface. This technique is documented in the The View's May/June 1998 article, Designing Friendlier, Easier UIs for Dynamic Tables, by Betsy Thiede.
2.7.3 Editable Rich Text Table with Data Extraction
In this technique, give the user an editable field into which a default formula uses @DbLookup to retrieve a rich text table stored in a hidden system document. In this editable field, the user can enter any text data into any cell in any order. The user can hit the tab key or a button you provide while the cursor is in the last cell to add a new row. When the user saves the document, a script routine can parse out the text from the table cells into Notes fields for data validation, reporting, or view display purposes. The following script from the Lotus Notes KnowledgeBase demonstrates the capture of text from cells in a table. Note that the document must be saved before the code will work:
To significantly reduce the rendering time of a Domino web form with non-editable data in tables, consider replacing all native Notes tables with pure HTML table code on the form or in a computed for display field to be rendered dynamically based on field values. Here is a formula example that will generate an HTML table for 5 columns of virtually unlimited rows, depending on the number of values in the multi-value fields assigned to c1 through c5.
Proper placement of graphics can speed up the loading of Domino pages. Rather than maintaining multiple copies of a logo, graphical button, or other reused image, attach the image file in a dedicated document accessed through an "images" view. Then use the HTML <IMG SRC> tag on your Notes form to point to the URL of the image file document. This results in a single point of maintenance as well as a consistent URL for all instances of the image, which allows the browser retrieve the image file from the browser cache after the initial retrieval. This also facilitates a single point of maintenance for graphics that may change. For graphics that are unlikely to change, consider placing the image file in the Domino HTML directory. Such placement affords the fastest HTTP service than when those Notes bitmap graphics have to be converted to JPEG or GIF format on the fly by Domino. In R5, you can design shared resources for this purpose. Images on a form or page in R5 can be stored in their native format. For performance, you can re-insert any embedded graphics from your R4.x applications into the R5 native format. Note, however, that R4.x clients will not be able display those graphics.
Images with fewer colors and smaller resolutions will be smaller and therefore load faster. Almost any image scanned with a scanning software's default settings is going to be unacceptably large. Use 50 to 72 dots per inch (dpi) resolution for images, and only use 256 colors for photograph quality images. Also keep in mind that JPEG is generally a more efficient format for photographs, while GIF format renders sharper icons.
For most web applications, try a browser disk cache of at least 5 MB, and a RAM cache of 1 MB. For intranet applications with many graphics, suggest to your users that they increase their browser cache settings. This will allow faster rendering of, and fewer server requests for, frequently accessed content. Make sure that on MS IE, however, you don't set the cache settings such that the browser never reloads a previously visited page, and user sees what appears to be an old version of a document.
Frames have the potential to improve page loading time since they isolate the portions of a page that will change. Framesets are possible in any version of Domino. R4.6 ships with a frameset template, which allows you to easily add a frameset to any existing Notes database or create one from scratch, without any knowledge of frameset HTML. R5.0 includes a native frameset design element that works in the Notes client as well as the web.
2.10 Optimize content storage format (web only)
In an extremely high volume database, it is important to use the most efficient content storage format that affords acceptable maintainability and security. The following list shows different formats of Notes content storage in order of decreasing performance.
If formulas exist on your forms, and you are using Notes 4.61 or later, you can take advantage of the Command Cache Formula Analyzer by adding the following line to the server's NOTES.INI file
In Domino R5.0, this parameter is enabled by default. In 4.61 and subsequent 4.6x builds, it is not. This setting will cause Domino to analyze all formulas for their dependencies through the Formula Analyzer. Rather than exclude all pages that contain any formulas from the Command Cache, the Formula Analyzer intelligently examines the formula on the page and decides its level of volatility. Domino can decide immediately whether the command is too volatile to be cached. For example, if the Web page contains @Now, Domino will not cache the page.
Because of its conservative nature, the Formula Analyzer errs on the side of not caching pages in order to guarantee the correctness of the page returned. You may decide that certain pages can be cached where the server determines that they cannot be. Lotus has provided controls so that you can override the cache behavior where appropriate. The following fields can control the use of the cache to some extent:
For Notes forms that do not use dynamic keywords and do not undergo frequent design changes, consider copying from your browser the source HTML generated by Domino and placing it in a flat file in the domino\html directory. The new URL to this static version of the form is simply http://server\FastForm.html. The benefit of this technique is that domino does not have to access the Notes database, evaluate security, form properties, and formulas, and render the form into HTML for each create request. Instead, it can simply hand the HTML file to your browser, which is much faster in extremely high volume environments. The submit process still goes through the Domino HTTP server as long as you don't change form field names or the UNID of the form element. This technique was used to support a feature for visitors to create documents on the Nagano 1998 Olympics website created by IBM with Domino 4.5.
The existence of a field named HTML on a Notes document will cause Domino to serve the contents of that field to the web client as HTML, bypassing everything else such as form properties, events, fields, and static rich text.
The form property "Treat document contents as HTML" yields similar results, but not as good performance as the HTML field. When this property is set, Domino converts all data on the document, the form, and subforms, to HTML. Domino ignores embedded navigators and folders and any embedded views that don't have the property "Treat view contents as HTML" selected. Pass-Thru HTML, [ ] delimited text, and the "HTML" style yield similar performance, but act selectively upon the document contents.
Plain text and rich text are evaluated on the fly by Domino. Rich Text incurs the added task of evaluating any embedded text styles, tables and graphics.
2.11 Replace Rich Text Fields With Text Fields (web only)
Some fields appear to be best presented to the user using Notes rich text fields to yield multi-row editable fields on the web. However, Domino takes more time and storage space to render and save a rich text field than it does a plain text field. Follow these steps to make the Description field (Notes text data type) for a document capable of multi line input, but not rich-text:
When specifying a result URL in a $$Return field or a WebQuerySave agent Print statement, use double brackets around the URL (if the page is on the same server) for faster performance. Without the double brackets, the server sends the URL to the browser, which requests the URL from the server, where the request is processed and the resulting page is finally served to the browser. This involves two round trips from the browser to the server. With the double brackets, Domino processes the request and sends the page to the browser immediately.
2.13 General Application Design Performance Considerations
From customer feedback, some limited testing, and information about Notes Database Internals, certain tips and techniques have become standard issue for Large Application Development. These points, from the Lotus Notes Knowledge Base, are briefly laid out below.
2.13.1 Design Elements
Minimize the use of subforms and shared fields, as each instance of these items causes Domino to open a new Note in addition to the document and form. Unfortunately subforms and shared fields are the basis of reusable user interface modules in Notes. The lesson here is to not overuse them; more than a handful of subforms or shared fields will likely cause a noticeable increase in the time to render a document.
Use profile documents to store database configuration settings and user-specific data. Profile documents are stored in memory on the Notes client workstation the first time they are used in a database session. After the initial usage, subsequent accesses to the profile document are performed in memory, allowing flexible high performance access to dynamic data. This is especially useful for storing user preferences as well as database information such as the paths to other related databases in an application suite.
2.13.2 Designing for Web and Notes Clients
When designing hybrid applications for both web and Notes clients, you will be tempted to use a single version of each form for both audiences. For complex forms, this will require significant hide formulas, which incurs additional server processing each time a form is loaded. Instead, consider creating a web-only and a Notes-only version of each form (or view or navigator). Use the Design Properties box to hide them from the inappropriate audience. Give both related design elements the same alias name so you can use that alias name in formulas. For example, if you create forms named NotesMain (hidden from web) and WebMain (hidden from Notes 4.6x and later) and assign them each the alias Main, Domino will automatically use the correct one of these forms for any document where the field form contains the value "Main". Domino presents the NotesMain form to a Notes client, and presents the WebMain form to a browser client. This technique gives better performance than multiple hide-when conditions or computed subforms.
Consider using "Private, Shared on First Use" views or folders instead of shared views of documents with Readers restrictions.
According to Walt Simons of the IBM Endicott Integration Center, shared view may open more slowly when the user only has access to a small percentage (<5%) of the documents in a relatively large view (>2000 documents). This is because the server must scan through the documents in the view until it finds enough to deliver a page-full of results (usually 30 on the web, and more in Notes client depending on screen resolution and view fonts). If a user only has access to 10 documents in the entire view of 100,000, the server must visit all 100,000 before it can determine that there are not 30 to display. To counteract this effect set the view property "Collapse when database is first opened" to true and categorize the view to segment the volume of documents in the view so each category has a small enough number to make response times reasonable. Alternatively, create a non-restrictred "summary" document for each restricted document that contains a doclink to the restricted document. The user can quickly navigate the view of all non-restricted documents, and a doclink launch event on the summary form automatically takes them to the restricted document. The tradeoff is that you essentially sacrifice the ability of Notes to exclude from view the records to which a user does not have access. But the improvement in navigation time can be 1000%.
Documents with Readers fields containing the user's explicit user ID display in a view faster than those which use groups or roles.
Allow Anonymous access in the database ACL for web applications where feasible. Domino caches the commands it uses to display pages to Anonymous users, but not to authenticated users.
Minimize the number of SUMMARY fields in each document. Under Document Properties, if the Field Flag is set to SUMMARY, then that field information is displayable by the view. That means that the view index has to store that field's information. All fields other than Rich Text fields, and fields created by LotusScript routines are SUMMARY fields. This property can be set by LotusScript. Note that a field whose SUMMARY property is False, will be set back to True if the field is displayed through a form and saved. To prevent non-summary fields from becoming summary fields, don't include the field on the form. Instead include a display version (using a different field name) as computed-for-display or editable and put the name of the non-summary field in the field value formula or the default value formula.
The space required for header information for a blank or empty field is approximately 7 bytes. This means that if you have 50 blank fields in 10,000 documents in a database, there is approximately 3.5 mbs of wasted header space / information.
Note from the chart below that transactions per minute is not affected by the size of the database. Rather, it is a function of the number of users on the server simultaneously. In fact, a larger database that contains its own reference data for lookups will generally perform faster than if the lookup data was partitioned on another database file. This is because lookups to the same database are faster than lookups to other databases.
Domino application performance tuning is an art that combines an understanding of Notes, your intuition, and trial and error. To complicate your performance efforts, there is a tradeoff between performance, functionality, and maintainability/cost. It has been said that of these three desireable characteristics of a software system, you can only pick two. Generally, functionality is a hard requirement. So you're left with tradeoffs between maintainability and performance.
With a new file storage structure and other improvements to the Notes core, Lotus has done their job to improve overall performance in R5. With an understanding of what causes various application performance problems, what can be done, and how it will affect maintainability, you can do your part to optimize the performance of Notes applications for your organization.
In exploring your application for improvement potential, don't forget that the Domino server configuration is usually a large performance factor. Due to its many capabilities, there are numerous settings and options on the server that impact performance, several of which are specific to hardware and operating environment. And unfortunately, there are far too many to include here. For information on improving Domino server performance, see the numerous articles and presentations available at http://www.lotus.com/performance and http://www.notes.net.
Copyright (c) 1999 Martin Scott Consulting LLC