【问题标题】:Why SAPUI5 loads similar fragment several times?为什么 SAPUI5 会多次加载类似的片段?
【发布时间】:2020-02-15 14:52:55
【问题描述】:

我有一个 XML 片段,并在 XML 视图的多个地方使用它。

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

但视图加载时间过长,尤其是在 WEBIDE 中。

原因是它多次加载类似的片段文件。这是一个证据:

问题是如何提高性能?

我不想重复代码,我需要将那部分代码放在一个片段中,但我希望我的浏览器不会多次加载同一个文件。

【问题讨论】:

    标签: performance caching sapui5 sap-web-ide sap-business-technology-platform


    【解决方案1】:

    在这种情况下无需更改您的代码。 SAP Web IDE / SCP 利用 App Cache Buster 开箱即用的概念,只要这些资源之前未更改,它就会从浏览器缓存中获取应用程序资源(例如片段)。

    请看下面的示例截图:

    给定

    • 代码:

      <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" />
      
    • Web IDE 在应用启动时自动附加的 URL 属性 sap-ui-appCacheBuster=...(描述 sap-ui-cachebuster-info.json 的位置)
    • 如果开发工具已打开:禁用缓存 未选中

    结果

    如您所见,片段(和其他资源)是从 磁盘缓存 加载的,而不是一次又一次地重新获取它们。

    此外,如果为最终生产环境捆绑应用程序,则这些片段甚至不会被多次请求,因为它们通常已包含在捆绑文件中(例如Component-preload.js)。


    【讨论】:

    • PS:除了上面的答案,请注意片段仍然通过 sync XHR 加载,即使使用 Fragment.load,这会显着减慢页面加载速度(如果从缓存被禁用)。但是应该修复:github.com/SAP/openui5/issues/2462
    • 我是否正确理解 Application Cache Buster (AppCacheBuster) 仅与具有 SAP 后端的应用程序以及在所有其他情况下相关,例如Node.js 后端,AppCacheBuster 无关紧要?
    【解决方案2】:

    如果您不在 webide 测试环境中运行您的应用程序,则应从缓存中加载片段。

    但是,您可以在控制器中加载片段并使用工厂函数而不是模板。比如:

    查看:

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

    在你的控制器中:

        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);
        }
    

    片段:

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

    【讨论】:

    • 我会尝试,但你可以用一些代码来支持你的答案,然后如果它有效,我可以选择它作为正确答案。
    • 只有当我们直接使用items 时才有用,在某些情况下,比如 SmartTable,它并不是很有用的解决方案。
    • SmartControls 的操作非常有限!但是,您可以尝试添加一个占位符视觉对象,并在渲染后将其替换为您的片段。但这不是一个非常漂亮的解决方案
    猜你喜欢
    • 1970-01-01
    • 2014-04-20
    • 2016-03-28
    • 1970-01-01
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多