This blog post is part two of a two part series about Best Practices for K2 practitioners. You can find part one, which was all about Blackpearl workflow tips and tricks, here. However, this article reads as a standalone piece, also. The great thing about K2 software is that there are many different ways of doing things and a negative thing about K2 is that there are many different ways doing of things! Poorly designed workflows and SmartForms can have a major effect on solutions’ performance and this can seriously impact the business motivation to adopt K2. Also, debugging complex forms can quickly become nightmarish when handing over to other developers of working backward through someone else’s implementation. Although some of the new, planned features in 4.6.9 (comments at last!) go some way to addressing this, following best practice will allows for a consistent approach to designing forms and workflows, thus making it easier for someone else to logically pick it apart. There is plenty of good documentation out there in the help files, forums and blogs but how do you find it if you’re not sure what to look for? So, we’ve complied some of the best tips available and added a fair few of our own to help budding developers get the most out of K2.

Rule Execution Types... When is the best time to use each one?


’Then’, means one after another and executes sequentially:
  • The first action executes, waits to complete, and then executes the next one.
  • All actions in one execution block will complete before the next execution block will start executing the actions within that secondary block.
  • Execution is performed in a synchronous manner.

2015-04 Blog - K2 Part 2 Image (1)Execution time: 26 seconds before next execution block is started. This approach is usually the slowest, but users can work on one item while the other is busy loading.  

’Also’, means in a batch:
  • All the actions are grouped in a single execution packet and the runtime executes the packet in a batch on the server.
  • Typically used for master or detail list of items, or single save scenarios as it causes bigger packets to be handled to and from the server.
  • It is not a true transaction as there is no rollback.
  • The K2 Service Object layer supports transactions, but SmartBox, which K2 Smartforms uses, does not support transactions. If there is transactional support on the method call on the Service Object, then it is supported by K2 Smartforms.
2015-04 Blog - K2 Part 2 Image (2)Execution time: depends on the server’s process time for the entire batch before the next execution block is started. This approach results in less data transfer over the network, but the UI can appear locked while the batch action is performed.

 

’And’, means concurrently:

All the actions start at the same time and wait for all the actions in the execution block to finish before going onto the next execution block. A good example is when using the Load/Initialise rule event; all the ’Get Lists for Views’ or ’Drop Down Lists’ can be populated together instead of waiting for one to finish before continuing to the next. Execution is performed in a parallel, asynchronous manner with a delay until all actions have been completed before continuing with the next execution block. 2015-04 Blog - K2 Part 2 Image (3)Execution time: 8 seconds before next execution block is started.  

Asynchronously:
  • All the actions start at the same time, when the first action completes the second execution block starts.
  • Execution is performed in an asynchronous manner. This is useful for non-dependent actions.

2015-04 Blog - K2 Part 2 Image (4)Execution time: 5 seconds before next execution block is started. This approach often results in the fastest user experience, but at the cost of network data transfer.  

Performance

K2 provide a list of tips in their documentation and we have picked out the most useful ones for this relevant blog:

Tweak, Enhancement or practice

Background and Notes



Install K2 smartforms and K2 blackpearl on the same server

Installing K2 smartforms and K2 blackpearl on the same physical server can help to improve performance.



Use hidden controls to launch Subforms/Views that are used more than once in a Form

When re-using the same View or SubForm multiple times in a parent Form, the parent Form copies the Rules of that SubForm/View for every Rule where you call the View or SubForm. To avoid this overhead and bloat, use a hidden button action to launch the View/Form with different inputs so that the Subform is only imported once.



Enable paging for read-only list views

When using read-only List Views for larger datasets (>50 records), enable paging for the list view to limit the number of records returned on the View Load. You can adjust the number of records per page in the View Rules. Since paging is performed on the K2 server, this can save the amount of data transferred to the client at runtime.



Filter data as close to the source of the data as possible

Where appropriate, use server-side filtering to limit the data returned to the SmartForm. You can define the filter in the View, or if you have static filtering requirement, implement a method with a static-value parameter in the SmartObject definition.



"Execute SmartObject Method" can be faster than "Execute a View Method"

When a Form needs to retrieve a value from a SmartObject in a View, and the View does not contain the value yet, it can be faster to call the SmartObject Method directly from the Form rather than calling a Form Event to retrieve the SmartObject property. In these cases, use the "Execute a SmartObject method" action rather than the "Execute a View method" action.



Keep the number of Form States for a Form to a minimum

Whenever you define a new Form State, all the Rules for the Forms are duplicated for the new State. Try to limit Form States to only those states that are necessary, or re-use States where possible. When the Form States differ significantly, it may be easier to define a separate Form than try to handle all possible scenarios in one Form definition.



Limit Rules and Actions to only what’s necessary

Avoid performing unnecessary Rules/Actions on a Form or View. For example, it is not always necessary to re-initialize a View. Clearing a View’s controls can "clean" the View for input without needing to re-populate the drop-down items on the View, for example.

Another example: when you add a View to a Form, the Form Initialize rule is automatically updated to include an Action which executes the View’s "Initialize" Rule, even if the View doesn’t have an "Initialize" Rule defined. Make sure that Initialize rules are executed only for the Views that actually have "Initialize" Rules defined.



Define separate Views for List views in read-only and edit mode

If you need to re-use the same List View in both Read-Only and Edit modes on different forms, it may be worthwhile to define separate List "Edit-mode" and List "Read-Only" mode views for the List View. Adding complicated Rules to enable/disable editing conditionally on a list view with many Expressions/Rules and Validations can impact runtime performance and complicate development.



Load data only when necessary

Wherever possible, try to load data only when it is required. For example, do not unnecessarily populate drop-down lists on hidden tabs, or do not unnecessarily populate a list view on ’Initialize’ if the List View will be populated by a subsequent action anyway. When using Tabs, populate the first tab in one Execution Block and then populate the remaining tabs in separate Execution Blocks. Where possible, delay the population of the other tabs/views until they are actually needed.



 

Simplification

Tweak, Enhancement or practice

Background and Notes



"Wrap" complex or re-usable Rules into a control Event and call the control’s Event to execute the Rule group.

If you have complex Rules that are used multiple times, it is a good idea to "wrap" those rules into a control event (for example, a hidden button). When you need to execute the Rule, use the "Execute a Rule" Action to call the "click" event of the hidden button to execute the Rule.  This approach allows you to define a complex Rule once and re-use the same Rule in different places. It can also reduce the size of the form definition sent to the client and improve runtime performance. Use the Name and Text/Watermark of the hidden control to document the control’s purpose.



Group-related hidden controls


For a group of hidden controls that are related, it is a good idea to group them within a table.  You can then hide the table instead of hiding all of the controls within the table separately, this is useful for when using multiple show/hide rules or for debugging hidden data labels.



Think of buttons as functions

It is a good idea to use the button control similarly to how you would set up a function if writing some code.  Grouping some reusable rules together within a button and then calling the button with the “execute another rule” rule can make it easier to zero in on the cause of defects by disabling the button (and the rules it contains) and makes the rules in a form much more readable/logical to other developers.

 

Debugging

You can enable the Smartforms debugging console by appending the query string ?_debug=level of debugging to the view or form a URL and review the log output while you perform actions in the Form. This lets you see the sequence of Rules that are executed. Levels: 1 = Debug 2 = Message 3 = Info 4 = Warning 5 = Error   And that’s it for the second part of the K2 Best Practices blogs - for the time being! If you have any further questions or are curious about how Datalytyx supports K2 solutions, please contact info@datalytyx.com. We would also like to recommend you check out the K2 naming conventions document. References: Smartforms Implementation Tips - http://www.k2.com/files/7833 Rule Execution Types - http://help.k2.com/KB001432