Skip to Content

“Load data when it’s actually needed. Do not load data in advance.” – Lazy Data Access principle, the main Web Dynpro principle.

In the short article I’ll try to show how to bring ‘lazy’ behavior to Tabs in TabStrip UI element. Under ‘lazy’ tab I mean the tab which does not create its content and does not load its data until the moment when user actually activates the tab. In some cases when the tab content is heavy this would make initial appearance of your UI much faster. Let me start with the beginning…

Popular TabStrip design

Very often we represent a Tab content as a view container element. This allows us to move a content of each tab to the separate external view responsible for the partial TabStrip aspect. From architectural point of view such solution is good, because allows us to use a component design concept.

<image was deleted by SCN3.0 migration>
   TabStrip design

<image was deleted by SCN3.0 migration>
   TabStrip window navigation diagram

Now let run the TabStrip…

However, let me do with such TabStrip a simple thing – insert log messages into each external tab view that will clarify us a little bit a life-cycle of the views. I inserted the corresponding log messages in methods wdDoInit() and wdDoModifyVew(…) of the views. These two methods indicate the phase of view creation and the phase of UI elements tree building.

Additionally to indicate the phase of data loading I inserted log messages “TabN: load data…” in all the supply-functions of the tab views. The supply-functions are responsible for data loading and bound to the views’ content elements. In my example each tab content is represented with a single input field.

<image was deleted by SCN3.0 migration>
      Second and third tabs are initialized in advance

As we can see according to the log messages the content of the first default tab is fully created and initialized with a data. This is good.

However, the second and third tabs are also created (methods wdDoInit() & wdDoModifyVew(…) of the views are invoked). This is not very good, because user did not clicked on them yet!

In more complicated applications with deep hierarchy of UI components embedding the unnecessary tab view initialization would pick up additionally initialization of all the embedded UI components with their default views, controllers, context structure, dictionary types, etc. All this could bring additional overhead in a performance of the application.

image
   Complex components embedding in a tab

Now let try to switch off the unnecessary tabs initialization…

Prerequisite: FAST tabAlignment property

For ‘lazy’ tabs use only tabAlignment=FAST.

To understand why FAST, please, read the SAP documentation on tabAlignment=EXACT: “Forces each client to exactly align the tabs’ widths and heights, i.e. all tabs  will have the same width and height, which is at least the given minimum and  what is required by their content. BEWARE Forcing a browser based client  to make all tabs equally wide and high is extremely inefficient.”.

The tabAlignment=EXACT will calculate the real width and height of each tab. Practically this means that WebDynpro will load all the tabs in advance, build trees of UI elements and load all the tabs’ content data (all your supply-functions will be invoked too). That’s why the option is “extremely inefficient”.

If you still need to have all the tabs equally wide and high set the explicit width and height properties in the TabStrip or in the Tabs’ content containers.

Disable Default Tab View Usages

The second reason of unnecessary tabs initialization in the scenario is not even related to TabStrip element, but to external view usages. As you can see on the picture above usages Tab1View, Tab2View and Tab3View are default on the window (default=true, color is blue). This means WebDynpro will initialize them anyway because they are active on the window and must be shown. Window does not know anything about TabStrip.

Here I propose the following trick which I successfully implemented in my application.

  • Add to each tab view container excepting the first one an usage of EmptyView and make it default.
  • Add N-1 outbound plugs to the main TabStrip view: activateTab2, activateTab3.
  • Establish navigation links. When tabN (N>1) is clicked we should navigate to the viewN of the tab.

<image was deleted by SCN3.0 migration>
      Enhanced TabStrip navigation diagram

Add the following code in OnSelect event handler of the TabStrip which activates the corresponding plug:

public static void wdDoModifyView(IPrivateTabStrip2View wdThis, IPrivateTabStrip2View.IContextNode wdContext, com.sap.tc.webdynpro.progmodel.api.IWDView view, boolean firstTime)
{
    //@@begin wdDoModifyView
     if (firstTime) {
        IWDTabStrip tabStrip = (IWDTabStrip) view.getElement("TabStrip");
          tabStrip.mappingOfOnSelect().addSourceMapping(
               IWDTabStrip.IWDOnSelect.TAB,
               IWDTabStrip.IWDOnSelect.TAB);
     }
    //@@end
}
public void onActionSelectTab(com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent, java.lang.String tab )
{
    //@@begin onActionSelectTab(ServerEvent)
     if ("Tab2".equals(tab)) {
          wdThis.wdFirePlugActivateTab2();
     } else if ("Tab3".equals(tab)) {
          wdThis.wdFirePlugActivateTab3();
     }
    //@@end
}

Result

Now when we open our TabStrib only the first tab is being loaded. All others will be loaded when user clicks on them first time.

<image was deleted by SCN3.0 migration>
      Only the first tab is loaded

To report this post you need to login first.

6 Comments

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

  1. Daniel Ruiz
    I’ve read your blog entry.. the info is quite useful, most of all because I guess anyone that works with WDP and do anything more complicated than a CRUD faced some similar problem.. by similar I mean “WDP problems” in doing what the framework is supposed to do.

    TabStrip is in a top-level View.. this View needs to be initialised, but I still can see no reason why the underlying ones are being.. either use ‘load when it’s visible’ or implement some loading method like any other framework has..

    (0) 

Leave a Reply