5

I have an XML fragment and use it in several places in an XML view.

<IconTabFilter text="ABC" key="1" icon="sap-icon://alphabetical-order">
    <content>
        <Table id="table1" width="auto" items="{path:'/ContactSet',parameters:{expand:'BusinessAddress,HomeAddress,OtherAddress,Photo'},filters:[{path:'Surname',operator:'StartsWith',value1:'A'},{path:'Surname',operator:'StartsWith',value1:'B'},{path:'Surname',operator:'StartsWith',value1:'C'}]}" noDataText=" {worklistView>/tableNoDataText}" busyIndicatorDelay="{worklistView>/tableBusyDelay}" growing="true" growingScrollToLoad="true" updateFinished="onUpdateFinished">
            <headerToolbar>
                <core:Fragment fragmentName="de.cimt.cimply.AddressBook.view.worklist.tablesHeader" type="XML"/>
            </headerToolbar>
            <columns>
                <core:Fragment fragmentName="de.cimt.cimply.AddressBook.view.worklist.tablesColumns" type="XML"/>
            </columns>
            <items>
                <core:Fragment fragmentName="de.cimt.cimply.AddressBook.view.worklist.tablesRows" type="XML"/>
            </items>
        </Table>
    </content>
</IconTabFilter>
<IconTabSeparator icon="sap-icon://process"/>
<IconTabFilter text="DEF" key="2" icon="sap-icon://alphabetical-order">
    <content>
        <Table id="table2" width="auto" items="{path:'/ContactSet',parameters:{expand:'BusinessAddress,HomeAddress,OtherAddress,Photo'},filters:[{path:'Surname',operator:'StartsWith',value1:'D'},{path:'Surname',operator:'StartsWith',value1:'E'},{path:'Surname',operator:'StartsWith',value1:'F'}]}" noDataText="{worklistView>/tableNoDataText}" busyIndicatorDelay="{worklistView>/tableBusyDelay}" growing="true" growingScrollToLoad="true" updateFinished="onUpdateFinished">
            <headerToolbar>
                <core:Fragment fragmentName="de.cimt.cimply.AddressBook.view.worklist.tablesHeader" type="XML"/>
            </headerToolbar>
            <columns>
                <core:Fragment fragmentName="de.cimt.cimply.AddressBook.view.worklist.tablesColumns" type="XML"/>
            </columns>
            <items>
                <core:Fragment fragmentName="de.cimt.cimply.AddressBook.view.worklist.tablesRows" type="XML"/>
            </items>
        </Table>
    </content>
</IconTabFilter>

But the view takes too long to load, especially in WEBIDE.

The reason is it loads similar fragment files several times. Here is an evidence:

Show how SAPUI5 loads xml file

The question is how can I improve the performance?

I don't want to repeat the code and I need to put that part of the code in a fragment, but I expected my browser to not load the same file several times.

Boghyon Hoffmann
  • 13,472
  • 7
  • 49
  • 114
MJBZA
  • 3,579
  • 4
  • 34
  • 67

2 Answers2

2

There is no need to change your code in that case. SAP Web IDE / SCP leverages App Cache Buster concept out of the box, which fetches application resources (e.g. fragments) from the browser cache as long as those resources were not altered before.

See the sample screenshot below:

Given

  • Code:

    <core:Fragment fragmentName="demo.view.fragment.MyFragment" type="XML" />
    <core:Fragment fragmentName="demo.view.fragment.MyFragment" type="XML" />
    <core:Fragment fragmentName="demo.view.fragment.MyFragment" type="XML" />
    <core:Fragment fragmentName="demo.view.fragment.MyFragment" type="XML" />
    <core:Fragment fragmentName="demo.view.fragment.MyFragment" type="XML" />
    <core:Fragment fragmentName="demo.view.fragment.MyFragment" type="XML" />
    
  • URL attribute sap-ui-appCacheBuster=... which Web IDE automatically appends on app launch (describes where sap-ui-cachebuster-info.json is located)
  • If the devtool is open: Disable cache Unchecked <-- probably that was still activated in your case

Result

Loading SAPUI5 application resources from the cache

As you can see, fragments (and other resources) are loaded fron the disk cache instead of re-fetching them again and again.

Additionally, if the application is bundled for the final production environment, those fragments won't be even requested multiple times as they're typically already included in the bundled file (e.g. Component-preload.js).


Boghyon Hoffmann
  • 13,472
  • 7
  • 49
  • 114
  • PS: apart from the answer above, note that fragments are still loaded via _sync XHR_, even with [`Fragment.load`](https://ui5.sap.com/#/api/sap.ui.core.Fragment/methods/sap.ui.core.Fragment.load), which noticeably slows down the page load (If loading from cache is disabled). Should be fixed however: https://github.com/SAP/openui5/issues/2462 – Boghyon Hoffmann Nov 07 '19 at 13:47
  • Do I understand it correctly that `Application Cache Buster` (`AppCacheBuster`) is only relevant for the apps with the SAP-backend and in all other cases, e.g. the Node.js backend, the `AppCacheBuster` is irrelevant? – Mike B. Nov 19 '20 at 19:27
0

If you run your app not in the webide testing environment the fragements should be loaded from cache.

However, you could load your fragment in your controller and use factoryfunctions instead of templates. Something like:

View:

<mvc:View controllerName="test.test.controller.View1" xmlns:mvc="sap.ui.core.mvc" xmlns:core="sap.ui.core" displayBlock="true" xmlns="sap.m">
<Shell id="shell">
    <App id="app">
        <pages>
            <Page id="page" title="{i18n>title}">
                <content>
                    <List  items="{ path: '/myList', factory: '.myListFactory' }"/>
                </content>
            </Page>
        </pages>
    </App>
</Shell>

in your controller:

    onInit: function () {

        this.getView().setModel(new JSONModel({
            "myList" : [{
                "Name": "Test1"
            }, {
                "Name": "Test2"
            }]
        }));


    },

    myListFactory: function (sId) {
        if(!this._myListFragment){
            this._myListFragment = new sap.ui.xmlfragment("test.test.view.myListFragment", this);
        }
        return this._myListFragment.clone(sId);
    }

fragment:

<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core">
<StandardListItem icon="sap-icon://warning" title="{Name}" />

Khaos
  • 154
  • 7
  • I will try, but you can support your answer with some code, then I can select it as the correct answer if it works. – MJBZA Oct 22 '19 at 15:35
  • It is helpful only if we directly work with `items` in some cases like SmartTable it is not that much useful solution. – MJBZA Oct 22 '19 at 16:15
  • SmartControls are very limited to manipulate! However, you can try adding a placeholder visual and replacing it with your fragment after rendering. But it is not a very beautiful solution – Khaos Oct 23 '19 at 08:31