Performance Improvements

This document is still under construction. The completed version will be available in IFS Applications 10 Update 8.

Contents

Fetching multiple values in Commands

Every call adds an overhead for the round trip to the server. Take time to revise your commands to minimize the number of server calls needed. Ultimately, you should strive for doing only one server call when you initialize an assistant or dialog. Rather than using set of functions to fetch values, whenever possible try to use a function that returns a structure containing multiple values.

Example: In the projection, define the function with structure.

structure PersonDetails {
    attribute Name Text;
    attribute Address Text;
    attribute Region Text;
}
function GetPersonDetails Structure(PersonDetails) { parameter PersonId Text; }

Then in the client, you can access the attributes on the variable using the dot notation.

command GetPersonDetailsCmd {
    variable DetailsStructure {
        type = Structure(PersonDetails);
    }
execute { call GetPersonDetails(PersonId) into DetailsStructure; set PersonName = DetailsStructure.Name; set Address = DetailsStructure.Address; set Region = DetailsStructure.Region; } }

Replacing Get methods and Prefetch using \$expand

Improve performance by removing usages of:

Client syntax that can be used to get values into the client using references. This can be used instead of fetch attributes (use get methods) and prefetch attributes.

There are many projections where fetch attributes are created using API Get methods. Due to the performance related concerns about the usage of get methods such as the context switch between plsql and sql occur when using get methods which is a costly operation, it has been decided to use the odata feature called “\$expand” to enable using references instead of fetch attributes that uses the get methods. In addition to replacing the get methods, same feature is proposed to use instead of the prefetch attributes that are created in the projection model. When you use fetch or prefetch, those attributes are created in the main entity which is unnecessary in many cases, but with the \$expand implementation it will not create more attributes in the main entity but use the reference with a special syntax in the client model to get the values from referenced entity.

Syntax that needs to be used in the client is as follows:

<ReferenceName>.<AttributeName>

e.g.

field CustomerRef.Name;

Get methods
It is required to create a reference in the projection model:

reference PartNoRef(PartNo) to PartCatalog(PartNo);

Then it is possible to use it in the client model:

field PartNoRef.Description;
field PartNoRef.InfoText;

However, there can be scenarios where you cannot clearly define a reference like above, in that case it is fine to use the fetch attributes. But try to create references in all the possible places instead of using get methods.

Prefetch

It’s possible to get values using the reference (using above syntaxes) without adding new attributes to the main entity.

How does this work?

When the above syntax is used in the client model, odata \$expand feature is used to expand the referenced entity and return the values together with the main entityset as inline data in a single response.

Example-

If the reference name is “CustomerRef” which is created using CustOrdCustomer entity and referenced from CustomerOrder entity, the URL would be something like,

CustomerOrders?$expand=CustomerRef

Server response contains a structure like follows with inline data,

CustomerOrder - OrderNo - Objstate ….. - WantedDeliveryDate - CustomerRef (CustOrdCustomer) - Name - CurrencyCode - NoteId

Where can you use the syntax?

You can use the new syntax in the places where you use the regular attributes.

Example -

entity CustomerOrder {
   reference CustomerRef(CustomerNo) to CustOrdCustomer(CustomerNo)
}

list OrderList for CustomerOrder {
   label = "Customer Orders List - ${CustomerRef.Name}";
   field OrderNo;
   field Objstate {
      label = “Status”;
   }
   lov CustomerRef with CustomerSelector using Customers {
      label = "Customer";
      description = CustomerRef.Name;
   }
   field CustomerRef.Name {
      label = "Customer Name";
   }
   field CustomerRef.CurrencyCode {
      visible = [CustomerRef.CurrencyCode != null]
   }
}

What is \$expand?

It is the OData way of reading inline (eager loading) data in a single response.

What you could do with it?

You can reduce the number of client to server calls, where you used to get the navigated information. In other words, client can get the inline data in a single server response.

Avoid Get methods when validating

instead use copy attributes option from referenced data sources.

In IEE it is a common scenario to use the validate event to fetch dependent values using Get method calls.

In IFS Marble language, instead of using Get method calls in validations, it is possible to use copy attributes option from referenced data sources.

Here the option to get information from another entity as an editable value on the entity which also can be saved to the server. The normal scenario is to use that value as a default value which the user can change and which will be sent to the server.

To make this happen the attribute must already exist on the entity in the projection, and this is because it must be part of the entity to be sent to the server.

Example:

attribute OppDescription Text;
reference BusinessOpportunityRef(RefId) to BusinessOpportunity(OpportunityNo) {
    copy Description to OppDescription;
}

Here, when selecting Business Opportunity, it will set the Description to OppDescription field. The OppDescription field will also be set to dirty making it part of the data to be sent to the server when saving.

Use \$select functionality to get the data used by the Client

To achieve this, we use odata functionality \$select. This was implemented in the odata provider. When calling the entityset we use the \$select part in the URL with the used attributes in the page to get only the required data into the client.

Mainly we use \$select in the following places:

If you check the server call for the Entityset it will contain some \$select statements added to the main Entityset and references.

Example:

bring only the selected attributes:

CustomerOrders?$select=OrderNo,OrderType,CustomerNo,WantedDeliveryDate&$expand=CustomerRef($select=Name,Address),AgentRef($select=Name,ShopAddress)

As you might already have noticed, challenging part here is to identify the attributes that are used in the client. So, do you need to specify these select attributes in your client file?

No, you don’t need to do that. Developer studio and Client FW will take care of identifying all the attributes used by the Page/Element in all the possible ways and will add them into the appropriate \$select query option.

If you check the client metadata file (make sure you redeploy your local client files using latest version of Dev Studio) you can see a section called ‘selectAttributes’ for each element which contains a list of attributes used by the element.

There are some attributes we extract from the client side as well (Ex. – attributes used in override section of element, parent attributes used by the calendar, keys used when there is a binding, etc).

We also do a check from the client to make sure that attribute is available in the entity to avoid error responses that can occur because of having invalid attributes in \$select. If all the attributes in the entity are used, then we don’t add the \$select part related to that entity.