Skip to Content

After a blog on Performance Improvements for Design Studio 1.5 here is one more blog with Design Studio Performance best practices in general. Although these topics may have been presented in earlier blogs, here you’ll find them revised and updated to the current Design Studio release.

 

 

 

Minimize the Number of Data Sources Loaded at Application Startup

 

 

By default, all data sources are loaded in Design Studio at application startup. For Design Studio applications with few data sources the application starts in sufficiently short time in the browser. However, the more data sources a Design Studio application has, the longer it may take until the application appears in the browser, as the application has to wait until all data sources have been loaded. This waiting time may be perceived by users negatively. One possible remedy is to reduce the number of data sources that are loaded at application startup.

 

Experience shows that no more than 4 data sources (information islands) are needed right from the beginning because humans typically cannot process a higher load of information. Using 10 or more data sources right from the start of the application clearly exceeds this limit by a wide margin.

 

To disable the loading of a data source at application startup, set the data source property “Load in Script” to “true”.

 

LoadInScript.png

Later, when the data of the data source is actually needed (for example, when the user clicks a button), load the data of the data source in a Design Studio script with the Design Studio script method loadDataSource, for example:

 

DS_1.loadDataSource();

 

Incidentally, calling loadDataSource several times on a data source has no performance penalty, as all calls of loadDataSource following the first call are ignored.

 

 

Load Data Sources Only When Components Get Visible

 

 

Larger Design Studio applications may have components that are not visible right at application startup — think of TabStrips with several tabs, Pagebooks with several pages, or any component that is initially invisible and shown, for example, upon a button click. You can improve the startup performance of your application by only loading the data sources of the visible components and not loading the data sources of the invisible components yet.

 

For example, you have a Pagebook of several pages with each page displaying the data of a different data source. One way to implement this efficiently is to load a data source only when the specific page of the Pagebook is selected. Add the following Design Studio script to the “On Select” event of the Pagebook:

 

if ((PAGEBOOK_1.getSelectedPageIndex() == 0)) {

  DS_1.loadDataSource();

  // …

} else if ((PAGEBOOK_1.getSelectedPageIndex() == 1)) {

  DS_2.loadDataSource();

  // …

} else if ((PAGEBOOK_1.getSelectedPageIndex() == 2)) {

  DS_3.loadDataSource();

  // …

}

 

Recall from the previous section that you need to set the property “Load in Script” to “true” for all the involved data sources.

 

Note that calling loadDataSource several times on an already loaded data source is ignored and has no performance impact.

 

Incidentally, an even better version would exploit the fact that the page of the Pagebook which is visible at application startup (in this example this is the page with index 0 – but this is can be changed): Load the first data source DS_1 already at application startup (with its property “Load in Script” set to false) and use the following Design Studio script in the “On Select” event of the Pagebook:

 

if ((PAGEBOOK_1.getSelectedPageIndex() == 1)) {

  DS_2.loadDataSource();

  // …

} else if ((PAGEBOOK_1.getSelectedPageIndex() == 2)) {

  DS_3.loadDataSource();

  // …

}

 

 

When to Load Data Sources with Background Processing

 

 

The sections above implicitly suggest to avoid loading data sources at application startup when their components are not visible. If such an application design with few initially visible components is not possible, the following shows you how to improve the perceived performance of loading these data sources.

 

The idea is that the most important data sources are loaded first, while the less important data sources are loaded afterwards. While users focus their attention on components with data sources that are loaded initially, the Design Studio application loads the remaining data sources, which is not perceived as waiting time by the user. Loading the remaining data sources separately is done using a concept called “background processing”. Background processing consists of executing a Design Studio script in the “On Background Processing” event handler, which is executed asynchronously.

 

The basic steps are as follows:

 

  1. Configure the most important data sources such that they are loaded immediately by setting their “Load in Script” property to “false”.
  2. Trigger the background processing in the “On Startup” event handler with APPLICATION.doBackgroundProcessing().
  3. In the “On Background Processing” event handler load the remaining data sources with loadDataSource().
  4. (Optional) If loading the remaining data sources still takes a very long time (longer than the user would look at the components with the most important data source) and some of them are more important than the others you can load the remaining data sources in an iterative fashion.

 

For example, you have a Design Studio application with four data sources, the first two of them should be shown immediately. Then proceed as follows:

  • Set the property “Load in Script” to “false” for data source DS_1 and DS_2.
  • Set the property “Load in Script” to “true” for data source DS_3 and DS_4.
  • In the “On Startup” event handler call APPLICATION.doBackgorundProcessing() (this is often the last line after all the other initialization script code).
  • In the “On Background Processing” event handler load the data sources DS_3 and DS_4 with

    DS_3.loadDataSource();
    DS_4.loadDataSource();

 

If loading both DS_3 and DS_4 during the initial background processing take too long, you can split up their loading as described in step 4. While most of the steps above remain the same, the only step that you need to change is the last one:

  • Create a global script variable, for example backgroundAction of type String, which is used to indicate which data source needs to be loaded.
  • In the “On Startup” event initialize the value of backgroundAction before triggering background processing:

    backgroundAction = “LOAD_DS_3”;
    APPLICATION.doBackgroundProcessing();

  • In the “On background Processing” event add the following Design Studio script:

    if (backgroundAction == “LOAD_DS_3”) {
      DS_3.loadDataSource();
      backgroundAction = “LOAD_DS_4”;
      APPLICATION.doBackgroundProcessing();
    }
    if (backgroundAction == “LOAD_DS_4”) {
      DS_4.loadDataSource();
      backgroundAction = “”; // not necessary, but good programming style
    }

 

It is easy to see that you can extend this example with more iterations.

 

Incidentally, you can apply this concept not only in the “On Startup” event handler, but also in any other event handler, for example to trigger loading data sources when changing tabs in a Tabstrip component.

 

Note that background processing comes at a cost (for more details, see section “Background Processing Is Not For Free” in on Performance Improvements for Design Studio 1.5), so it’s best to use background processing only when needed.

 

 

Use a Single Data Source for Multiple Charts

 

 

When you have several charts, try to use a single data source with those charts and select the relevant data for the specific chart with the Chart property “Data Selection”:

 

DataSelection.png

This may involve redesigning the single data source as a superset of all the previously used data sources.

 

For example, you have one chart displaying data of a specific country, say Italy, and one chart displaying data of another specific country, say Spain. Then, instead of choosing two data sources – one for Italy and one for Spain – use a single data source containing country-specific data, including country-specific data for Italy and Spain. For the first chart use the Chart property “Data Selection” to select the data specific to Italy, for the second chart use the Chart property “Data Selection” to select the data specific to Spain.

 

Reducing the number of data sources in this way improves the performance significantly.

 

 

Selecting Data of Data Sources

 

 

There are several ways to select (or filter) data from a data source. They are discussed in the following list sorted by increasing performance:

 

 

setVariableValue

Lowest performance (if “Merge Prompts” is “true”), involves round trips to multiple data sources and potentially executes custom code on BW provided via “exits”.

Using variables involves the concept of a variable container. A variable container permits sharing of variables among multiple data sources. Therefore setting even a single variable with setVariableValue may affect multiple data sources, resulting in a larger performance penalty.

The sharing of variables is a very useful feature, therefore by default it’s turned on. However for functional or performance reasons the variable container can be turned off by setting the value of “Merge Prompts” to “false”). However setting a variable value even in “unmerged” mode has a higher overhead in BW that the other options mentioned below.

See Design Studio: Performance Implications of Variables for more details.

setFilter

Medium performance, involves round trips to a single data source

Contrary to setVariable, calling the function setFilter always affects a single data source only. Thus, if possible, prefer setFilter over setVariable. This may require restructuring the data source, for example by using the Query Designer for BW queries or HANA Studio for analytical views or calculation views.

setDataSelection

Highest performance, involves no round trip

While setVariable and setFilter operate on data sources, setDataSelection operates on components, selecting a subset of the data in the data source assigned to the component (at the time of writing only Chart and data-bound SDK components support setDataSelection). This involves no round trip to the data source and is therefore the fastest of the listed options. A common pattern is to configure the data source to contain a superset of the data of interest and then to select the actual data of interest to the component with setDataSelection.

 

Use “setDataSource” to Avoid Duplication of Components

 

 

Before Design Studio 1.5 the assignment of data sources was static and could not be changed at runtime. To “simulate” changing the data source of – for example – a crosstab, the application designer had to insert two (or even more – depending on the number of exchanged data sources) components at the same place, with the same settings. Later for one of these components the property “visible” was set to “true”, for the others “visible” would be “false”. If another data source should be shown these “visible” flags were changed accordingly.

 

This approach has the disadvantage of wasting resources because the number of components was higher than actually needed.

 

With Design Studio 1.5 this “simulation” by using the “visible” property is no longer necessary. With the “setDataSource” function the data source can changed as needed for every analytic component:

 

AnalyticComponents.png

 

 

Exchanging the data source can be done with a call to “setDataSource”:

 

CROSSTAB_TOP_N.setDataSource(DS_2);

 

 

Minimize the “Start Screen” of Your Application

 

 

Performance is a critical topic for all areas of an application. However the most critical area of an application is the startup time. The perceived startup time is the time between launching the application up to the appearance of the first useful information in the application.

 

The design of the “start screen” can influence startup performance more than any other technical topic. Ideally the start screen consists of components referring to one single data source showing the most important data for the user. With that information the user should be enabled to choose which information he wants to see next.

 

It is important to emphasize that having only one data source at startup does not mean the screen consists only of one component. One data source can be used to feed for example both a crosstab and a chart. With the “data selection” feature one data source can also be used to feed multiple charts (see chapter “Use a Single Data Source for Multiple Charts”). In addition this data source can be used to feed entries of list-boxes or dropdown boxes to allow the users choosing other views of the data or switching to other screens showing more detailed data.

 

The following screenshot shows a screen that is populated with information from a single data source:

 

StartScreen.png

 

 

Use “Page Caching” of the Pagebook Wisely

 

 

The property “Page Caching” of the Pagebook component controls which pages are rendered directly to the browser.

 

PageCaching.png

 

The default value of “None” renders only the currently visible page to the browser. Other pages are rendered when they become visible. The value of ‘”None” is the most efficient one in terms of performance.

 

The setting “Adjacent” is a good solution when the “Transition Effect” property is different from “None” and paging is done only to go to the “next” or “previous” page. During the transition effect both of the pages are at least partially visible. To make this work, these two pages must have been rendered to the browser before the transition is visualized.

 

The most advanced scenario (and also the most costly in terms of performance) is the use of transition effects in conjunction with the possibility to navigate directly to any page (that is, also to non-adjacent pages). This is possible by using the Pagebook’s API functions “setSelectedPageIndex” or “setSelectedPageByName”. Another possibility to navigate directly to non-adjacent pages is the Pagebook’s “Page Indicator”:

 

PageIndicator.png

 

It shows one grey circle for each page and marks the selected page with a filled grey circle. By clicking on any of the grey circles the corresponding page is made visible. For smooth transition effects from a page to any other page all pages must be rendered to the browser. This is where setting the property “Page Caching” to the value “All” would make sense. However this comes at a significant cost in performance because all pages of the Pagebook must be rendered.

 

From a performance point of view the value “None” is the best choice for the property “Page Caching”. So choose wisely when using other values than “None” and hereby trading performance for fancy transition effects.

 

 

Some Final Words…

 

 

This is a living document and will be updated with new information. Be sure to come back or subscribe to this page if you are interested and want to stay up to date on Design Studio performance topics. Also have a look at SAP note 1931691 covering Design Studio performance topics.

 

You might be also interested in the following blogs:

 

Design Studio 1.5 – The Performance Release

 

Design Studio: Performance Implications of Variables

 

Design Studio Tips and Tricks: Measuring Performance

 

Design Studio 1.5: View on Parallel Data Source Execution

 

Design Studio: Parallel Processing and Scripting

 

Design Studio: Why is HANA Studio Faster?

To report this post you need to login first.

17 Comments

You must be Logged on to comment or reply to a post.

  1. Mustafa Bensan

    Hi Martin,

     

    A very good reference, thank you.  I have a couple of questions regarding the section about Use “setDataSource” to Avoid Duplication of Components:

     

    1.  I thought that we could already avoid duplication of components using the assignDataSource method?  I assume that setDataSource has the additional benefit of supporting Universe data sources whereas this is not the case for assignDataSource. Is that right?

     

    2.  I notice that setDataSource is complemented by getDataSource which is very useful indeed.  However, it seems that neither of these methods are available for SDK components.  Can you confirm?

     

    Thanks,

     

    Mustafa.

    (0) 
    1. Martin Kolb Post author

      Hi Mustafa,

       

      thanks for your comment

       

      Let me answer both of your questions:

       

      1) “setDataSource” vs. “assignDataSource”

       

      The “assignDataSource” method is used for avoiding duplication of data sources. E.g. if you have ten Queries that shall be used in your application one after the other, then without “assignDataSource” you would need to create something like “DS_1” through “DS_10” referring to these queries. With “assignDataSource” the alternative is to create only a “generic” data source” and to assign these different queries when they are needed.

       

      Incidentally the “setDataSource” method is used to avoid duplication of components. For example you have an application with 3 visible crosstabs showing region data (e.g. EMEA, AMERICA, APJ). These crosstabs are using three data sources “DS_1”, “DS_2” and “DS_3”. If you have one chart in that app where the user can choose to show one of these regions in a chart, then (without “setDataSource”) you would need to have also three charts (assigned to “DS_1”, “DS_2” and “DS_3”) and show one of them according to the use selection.

      Now with “setDataSource” you can achieve the same with only one chart, where “setDataSource” is used to assign the region that shall be shown.

       

       

      2) “setDataSource” in SDK components

       

      In fact both methods are available with Design Studio 1.5. However they are not available automatically. In the “contribution.ztl” file of the SDK component, the implementer of the SDK component has to inherit from “DataBoundComponent” instead of “Component”.

      Details about this topic con be found in “Developer Guide: Design Studio SDK” on page 39:

      http://help.sap.com/businessobject/product_guides/AAD15/en/ds_15_dev_guide_en.pdf

       

       

      Regards

      Martin

      (0) 
      1. Mustafa Bensan

        Hi Martin,

         

        Thanks very much for your prompt and detailed response.  Point 1 makes complete sense now.  For Point 2, clearly I missed the tip on page 39 of the Developer Guide .

         

        Regards,

         

        Mustafa.

        (0) 
  2. sathish babu

    Hello Martin

    I found your blog very helpful, thanks a lot.

    I have a dashboard with tabstrips, and I applied background processing for data sources those are not in the first tab. However, when i click on other tabs, my datasource queries are running again. Do you have any experiences like this, why it could happen?

    Regards

    (0) 
    1. Martin Kolb Post author

      Hi Sathish,

       

      thanks for your comment.

       

      Without looking at the application I cannot tell why this happens. In most cases it is helpful to create a performance trace using the “&PROFILING=X” URL parameter and download the trace “as text”. Looking at this trace often reveals details that help to understand what is going on when running an application.

       

       

       

      But in general I recommend to not use “Background Processing” for your use case. If you have a tab strip component you should load the data sources on the “other” tabs only when they become visible. This is described for the pagebook component in the chapter “Load Data Sources Only When Components Get Visible” of this blog. But the same concept also applies to tab strip components. Otherwise you might load data for data sources that the user never sees, because he does not click on these tabs. This wastes resources on the data source sever (BW, HANA, …), on the network (transferring the data from the data source server to the design studio server), and also wastes the memory on the Design Studio server that must store the retrieved data. To avoid this waste I recommend to remove the “Background Processing” and use the “loadDataSource” API in the “On Select” event of the tab strip instead.

       

       

       

      Regards

      Martin

      (0) 
      1. sathish babu

        Thank you Martin for your valuable inputs.

        I was trying to minimize the waiting times during navigation. Anyway, i will try other solutions.

        Best Regards

        (0) 
      2. Andreas J.A. Schneider

        Hello Martin : )

         

        Just to clarify, assuming the user(s) will click through most if not even all the other tabs would then background processing of the data sources not make sense, performancewise?

        (0) 
        1. Martin Kolb Post author

          Hi Andreas,

           

          using backgroud processing makes sense when a user interaction takes quite long and can be split into a “fast part” and a “long running part”. In that case the “fast part” should be done directly in the event handler code and the “long running part” should be put into background processing.

          If tabstrips are used, the stuff in different tabs should always be done in the event handler of the tab strip, no matter if the user clicks through all the tabs or not. With this, the user has the performance advantage that the applications comes up faster, because the initialization of the “upcoming” tabs are done at the point in times when he clicks on these tabs.

           

          The mentioned use case above was a special case when explicitly a longer waiting time in the beginning was accepted for faster navigation between the tabs. In general user studies show that fast startup is much more important than navigation inside the app. But this decision must be done on a case-by-case basis and based on customer’s demands.

           

          Regards

          Martin

          (0) 
  3. Alexander Knight

    Hi,

    I have a particular problem in my Design Studio connected to SAP BW.  Normally the event “Get Connection” is around 600ms.  If I have a number of connections happening at the same time (either on start or background processing) then this particular event gets a lot longer, even if all the other events stay similar (get or submit variables for example don’t change).  Is there possibly a limit to the connections that BW can handle at once, or something else going on that I can optimise?

    I am seeing “get connection” times of 12+ seconds, so this is a big issue.

     

    Kind regards

    Alex

    (0) 
    1. Martin Kolb Post author

      Hi Alex,

       

      the first getConnection for an application (or for a processing group) actually creates a new session on the BW system. These calls to “getConnection” take significantly longer than those getConnection calls which simply retrieve an already open connection.

       

      There are limits of a BW system for the number of sessions to be created, but if these limits are reached, the getConnection would fail, rather than taking longer.

       

      However even if these limits are not reached, creating new sessions take a significant amount of the BW’s resources. So if you are working with processing groups, you should take into consideration that each of these groups creates a new BW session. So we recommend to not exceed 10 processing groups per application. Otherwise if you simply multiply the number of open applications (often related to how many users start this application) with the number of processing groups you will soon reach of number of BW sessions that can become uncomfortable for the BW system unless it is specifically sized to handle such an amount of sessions.

       

      Regards

      Martin

      (0) 
      1. Alexander Knight

        Hi Martin,

        that was what I suspected, thanks for confirming this.  I have tested grouping my queries into less processing groups, and of course I now get worse performance because the queries are now working in series.  The get connections are better but the total elapsed time is worse, and there is a knock throughout the app.

        You mention BW sizing.  Are there any documents you can point me too to help me understand how to optimize the BW size for this sort of application?

        Also, is there an issue that the sessions are staying open?  I know that in Portal when we close a BW query they also close the session, but the same isn’t happening in Design Studio I think.

        thanks

        Alex

        (0) 
        1. Martin Kolb Post author

          Hi Alex,

           

          I’m not a specific expert in sizing as it’s a huge topic on its own. As for the session count it is mainly related to giving the BW system enough physical memory to handle all the session content without the need to access the disc.

           

          The sessions of a Design Studio application to a BW stay open until the application is closed. In future versions of Design Studio it is considered to support “one shot” sessions that close automatically after the initial set of data has been fetched from BW. This is useful for example in applications in production plants that show the production status on hanging monitors, allowing no interaction for the users.

           

          If you experience that sessions in BW stay open even after the Design Studio application has been closed, then feel free to open a bug ticket that allows us to investigate this.

           

          Regards

          Martin

          (0) 
  4. Andrey Surinov

    Lesson learned: checking “Page Caching” should be the first thing in the morning, it can easily spoil the performance by a factor of several times, even if all data sources are ok.

    (0) 

Leave a Reply