Skip to end of metadata
Go to start of metadata

You are viewing an old version of this content. View the current version.

Compare with Current View Version History

Version 1 Current »

Asynchronous includes

The easiest solution for performance improvements is to make includes “asynchronous”. As a result, the following happens:

  • Workplace loads the requested object by the user

  • Workplace shows the object to the user

  • Once the loading of the object is done, Workplace starts to load the includes

  • Once the data in an include is loaded, the data is presented. This happens for all the includes at the same time (so a small include will be shown earlier than a large include)

This is compared to the default behavior:

  • Workplace loads the requested object by the user

  • Workplace loads all includes associated with the object by the user

  • Once all the loading is done, the user is presented with all the data at once

Even though the total performance on the server will not be improved, the PERCEIVED performance by the user will be improved.

For setting includes to be asynchronous, open the page definition, scroll down the includes include and either select all and change the value for asynchronous to “yes”, or open the ones that you would like to change and set the value to “yes”.

Dropdown fields

Dropdown fields are a nice way to present users with a specific set of values. It might also be a performance killer in case the filter behind the dropdown field is not correct. A common example is when creating a client specific field which ends with CodeTypeId. If Workplace cannot find the associated CodeTypeScheme, and you set the field to be displayed as a dropdown, it will return ALL the codetypes as possible options. Another example is when making a dropdown with Contacts which depend on the current object (for example a Workorder), but presenting that field in a report where there is no Workorder in the context (as you are on a report). The dropdown would then consist of all Contacts.

When implementing a dropdown field, take the following steps:

  • Create the field with which you can select an object (this is the only case where performance issues arrive)

  • Make sure the field is set to “object selection screen”

  • Add a filter if required

  • Navigate to the object or report and fill in the field. You should be presented with the set object selection screen. Run it “as is”. If everything went well, you should be presented with the values that you expect. If not, you know you have made a mistake and you can rectify it.

  • Once you get the result that you want, change the field to “object dropdown”

When analyzing a performance problem, always check the page for dropdowns. Check how many values are in there. In case of client specific fields, double check the filters and optional scripts that retrieve the values to see if there are suboptimal queries in those.

Large reports/includes

This one should be quite obvious, but reports with a lot of result with negatively impact the performance. Especially if these are added as an include to an object. If, for whatever reason, an asynchronous include is not possible, consider changing the filtering on these reports to give back a more limited set of data. This is mostly a functional decision:

  • Make sure large reports are run manually, so the user is aware of the report taking a long time

  • See if you can scale down the amount of data on an include, as an include should only present the user with data that is relevant for that object at that time

  • If you have dashboards for users, limit the amount of data on those (as well as make then asynchronous)

Scripting in reports

In reports, scripting can be used to execute more complex if necessary. A formula could look like the following:

execute("MakeComplexCalculation",WorkorderReference)

There is one downside to this: when passing values to the script (in the above case, “WorkorderReference”), these are passed as strings, NOT as objects. So that results in the scripting having to perform a second query based on the value. To sketch a hypothetical case:

  • A report returns 100 workorders

  • Based on those workorders, you pass the workorder reference to the formula script

  • You than do a query on the workorder reference, from which you get the values from the workorder and return a calculated value

The above situation results in 101 queries: one for the report, 100 for each consecutive line for which you make the calculation. A more performant option is to add all the necessary values that you need in the script in the report, hide them from the end result, but pass them to the formula. The formula call would be the following:

execute("MakeComplexCalculation",WorkorderPlannedAmount,WorkorderInvoicedAmount,WorkorderSupplierMultiplier)

In the script, you would then use the (string!) values to make the necessary calculations. This will result in 1 query for the complete report.

Client specific fields

Every time you create a client specific field, this results in an additional database call for every object made which has that field on it. At certain points, this becomes a performance killer (experience learns this is about 80 client specific fields where this becomes quite slow). So take the following aspects into consideration when creating client specific fields (or when debugging performance):

  • Make client specific fields on the lowest category possible. That will result in the fields only being created for a specific subset of objects

  • Only put a client specific field on a higher category level if more than 3 sub categories need it OR the subcategories in combination with the parent category are a limited subset

  • Look at the existing fields and see if you can re-use a field or not

  • Cleanup fields that are no longer used

  • If a lot of different fields are necessary, consider using an independent object (i.e. CodeType) with a specific category to put the fields on. This will prevent unnecessary fields on a specific object. Also, it might result in being able to create the independent object on a later time, which lowers the performance impact on the initial creation of the object

  • No labels