SAPUI5 apps are basically JavaScript files sent to a client by a server and interpreted by the browser. So it's not only the coding of the app that can cause slow performance. It often turns out, for example, that the configuration is wrong. Slow networks or servers may also have a heavy impact on the performance of a web app. Let's have a look at the most common issues that impact performance.
The first step of improving the performance of your application is the switch to asynchronous loading. This makes your application a lot faster, as things can run in parallel. SAPUI5 provides several configuration options that you can set. For more information, see Use Asynchronous Loading.
Additional Information:
sap.ui.core.IAsyncContentCreation
interfacemanifest.json
Instead of the Bootstrap to Define DependenciesDon't specify a link to the CSS in the bootstrap of your app; use the manifest.json
descriptor file instead.
Please use the manifest.json
application descriptor file to declare dependencies. This has several advantages:
Make sure that you don't load too many dependencies. In most apps it's enough to load the libraries sap.ui.core
and
sap.m
by default, and add additional libraries only when needed.
If you want to make additional libraries
known
in your app, without directly loading them during the app start, you can add them to the dependency declaration in the
manifest.json
file with the lazy
loading
option:
"sap.ui5": {
"dependencies": {
"minUI5Version": "1.70.0",
"libs": {
"sap.ui.core": {},
"sap.m": {},
"my.heavy.charting": {
"lazy": true
}
},
...
If a library preload is configured to be loaded lazily ("lazy": true
), the library isn't available upon creation of the related
component. In this case, you need to ensure yourself that the library is preloaded, e.g. via sap/ui/core/Lib.load({name:
"my.heavy.charting"})
, before any module from that library is used.
Additional Information:
In order to ensure that all static SAPUI5 resources are served with the lowest possible latency in SAP Business Technology Platform scenarios, you can load the resources from the Content Delivery Network (CDN) cached by AKAMAI. Especially when running your app in the cloud, you benefit from the global distribution of servers. For other scenarios, it possible to configure a custom CDN of choice as an external location.
Additional Information:
Languages can be configured in your manifest since UI5 version 1.77.
The manifest configuration for i18n has now the option to provide the supportedLocales
and the
fallbackLocale
:
supportedLocales
should contain all languages for which
you've
i18n files. e.g.,
a file named
i18n_en.properties
has the locale en
.fallbackLocale
is the locale loaded before falling back to the root bundle.Example: If the following language files exist:
i18n_en.properties
(English version, "en"
)i18n_de.properties
(German version, "de"
)They
can be configured in your manifest.json
in Section sap.ui5
under models
:
"sap.ui5": { "models": { "i18n": { "type": "sap.ui.model.resource.ResourceModel", "settings": { "bundleName": "sap.ui.demo.todo.i18n.i18n", "supportedLocales": ["en", "de"], "fallbackLocale": "en" } } } }
Wit'sh
AppDescriptor version 1.21.0 this is also possible in the i18n
section of sap.app
in your
manifest.json
:
"sap.app": { "i18n": { "bundleUrl": "i18n/i18n.properties", "supportedLocales": ["en", "de"], "fallbackLocale": "en" } }
For more information, see:
When creating a component manually, make sure the manifest.json
descriptor file is loaded first, so that the dependencies
are analyzed and preloaded when the component is loaded. For more information, see Manifest First Function.
If the library preloads are disabled or not found, every module is loaded separately by an own request. Depending on the server and network infrastructure, this can take a lot of time. Except for debugging reasons, it's always recommended to make sure library preloads are used. Fortunately, the library preloads are active by default if the files are present.
In some cases it may happen that preloads are not enabled, or that modules of some libraries are still loaded separately:
A subset of libraries in the sap.ui5/dependencies/libs
section of the manifest.json
is
declared with the lazy
loading option, but these lazy
libraries
aren't
preloaded manually before their modules are used. For more information, see Descriptor Dependencies to Libraries and Components.
Neither sap-ui-async
nor sap-ui-preload
is enabled in the bootstrap
configuration options. Note that if sap-ui-async
is set to
true
, the value of the preload configuration is automatically set to
"async"
.
data-sap-ui-debug=true
) or via the URL
(sap-ui-debug=true
).Application modules (e.g. components, controllers, views or resource bundles) should be loaded asynchronously via the component preload
file. Check (e.g. via the Network tab in the Google Chrome developer tools) if a component preload
(Component-preload.js
) is missing. If the application
isn't
configured to load modules asynchronously, required application files may be loaded synchronously.
If a component preload doesn't exist yet, the bundle needs to be created. For example, you can use the UI5 Tooling.
To quickly check the network load caused by your app, look at your browser's developer tools, for example the Network tab in the Google Chrome developer tools (F12). You'll see an overview of all requests being sent. Possible issues here may be:
In this case, use the data-sap-ui-async="true"
setting in the bootstrap.
You can use UI5 Tooling to bundle and minimize all relevant component files by creating a component-preload file.
Slow database service (e.g. OData)
Additional Information:
jquery.sap.*
Modules to their Modularised VariantsSince UI5 version 1.58, the global jquery.sap.*
modules are deprecated. Please use the modularised variant of the
module. If
you're
still using the jquery.sap.*
variants, a so-called "stubbing layer" may load the old module synchronously!
You can find a list of modules in the Replacement of Deprecated jQuery APIs documentation.
The usages can either be replaced manually or by the UI5 Migration Tool.
Please make sure to declare the required modules in sap.ui.define
or sap.ui.require
to ensure
that they get loaded asynchronously.
Check if the application uses synchronous UI5 factories. Many asynchronous variants are available, e.g. for Components, Resource Bundles, Controllers, Views, and Fragments. Please visit the following overview: Deprecated Factories Replacement.
Components can preload models for which modules are already loaded; otherwise a warning will be shown. The OData model (V2 or V4) benefits especially, because the metadata can be loaded in parallel during a component load.
"sap.ui5": { ... "models": { "mymodel": { "preload": true, ...
For the OData V2 model, also consider using the model parameter earlyTokenRequest
. For more information, see the API Reference:
sap.ui.model.odata.v2.ODataModel
.
For the OData V4 model, also consider using the model parameter earlyRequests
. For more information, see the API Reference:
sap.ui.model.odata.v4.ODataModel
.
For more information, see Manifest Model Preload.
To ensure fast loading times for SAP Fiori applications started from the SAP Fiori launchpad, the OData metadata
is cached on the web browser using cache tokens. The tokens are added with the parameter sap-context-token
to the URL
of metadata requests. Please check via the developer tools of your browser (e.g. the Network tab in the Google Chrome developer tools)
if the token has been appended to the request URL.
This feature is currently only supported for ABAP back ends.
Additional Information:
$select
Query when Binding an Aggregation in the OData V2 ModelWith a $select
query you enable your application to fetch only necessary properties of an entity from the
collection.
As an example, consider the EntityType "Customers", which is available from the public Northwind OData service at https://services.odata.org/V2/Northwind/Northwind.svc/Customers?$format=json. It has several properties.
If you have an sap.m.List
that only needs to display the CompanyName
from the collection, you could
add the following to your XML view:
... <List id="myList" ... items="{ path: '/Customers', parameters: { select: 'CustomerID,CompanyName' } }"> ...
Note that all key properties, such as the CustomerID
, should still be added, even though they're not directly relevant
to the user.
As a result, the response size of your application is reduced significantly. You also enable the back end to perform a more efficient database query.
In the OData V4 model, $select
and $expand
values can be automatically defined. For more information,
see Automatic determination of $expand and $select.
The performance limits are reached differently depending on the used browser, operating system and hardware. Therefore, it is important
to be mindful about the amount of controls and data bindings. This applies especially to lists and their variants (e.g.
sap.m.Table
or sap.ui.table.Table
):
sap.ui.table.Table
instead of
sap.m.Table
The reason for this is that sap.m.Table
keeps every loaded row in memory,
even if not visible after scrolling. To choose the right table variant for your requirements, check out the documentation
about Tables: Which One Should I Choose?Additional Information:
You can further optimize your code by doing the following:
Use asynchronous view loading as described here: Instantiating Views.
Use the OData V4 model, which has an improved performance over the OData V2 model.
Visit the OData V4 Model documentation and ensure that all required features are available.
For a quick start, follow the OData V4 Tutorial tutorial.
If you use data binding with an OData V2 service as a back end, you must not use the deprecated
sap.ui.model.odata.ODataModel
anymore. For more information, see OData V2 Model.
Optimize dependent bindings as described here: Optimizing Dependent Bindings.
Avoid the usage of setTimeout()
calls with values greater than 0
. This usually indicates
an anti-pattern in application code that is used as a workaround and should be avoided. For more information, see also
JavaScript Code Issues: Don't use timeouts.
Don't use visibility for lazy instantiation. For more information, see Performance Issues: Don't use visibility for lazy instantiation.
XML Preprocessor
is used, we recommend to use the XML View Cache. If configured in the XML View and with a properly implemented key provider (for invalidation), it is able to cache already
processed XML View Preprocessor results.