Why SAPUI5 loads similar fragment several times?
Asked Answered
G

2

6

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.

Glut answered 18/10, 2019 at 15:16 Comment(0)
K
3

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).


Knur answered 7/11, 2019 at 13:28 Comment(2)
PS: apart from the answer above, note that fragments are still loaded via sync XHR, even with Fragment.load, which noticeably slows down the page load (If loading from cache is disabled). Should be fixed however: github.com/SAP/openui5/issues/2462Knur
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?Leontine
I
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}" />

Inventory answered 22/10, 2019 at 15:15 Comment(3)
I will try, but you can support your answer with some code, then I can select it as the correct answer if it works.Glut
It is helpful only if we directly work with items in some cases like SmartTable it is not that much useful solution.Glut
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 solutionInventory

© 2022 - 2024 — McMap. All rights reserved.