Show TOC

Performance: Speed Up Your AppLocate this document in the navigation structure

If a Web app seems to have performance issues, finding out what's causing this can be both a time-consuming and nerve-consuming task. To help you avoid and maybe already solve performance issues in your app, here are some good practices we've discovered while dealing with SAPUI5 apps.

When it comes to performance, it's often the case that an app is immediately considered to be slow. But this is only half of the truth. Sure, the app is what can be seen, but what is actually the app? It is the sum of its coding, retrieved and executed in a specific environment.

For SAPUI5 apps, we basically talk about JavaScript files sent to a client by a server and interpreted by the browser. So it's not only the coding of the app the can cause a slow performance. In many cases, it turns out that the configuration is wrong, for example. 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.

Configuration
Issues with configuration are often caused by an old bootstrap or wrong usage of the activated features. Here's an example of what a bootstrap should look like for a modern SAPUI5 app:
<script id="sap-ui-bootstrap"
	src="sapui5/resources/sap-ui-core.js"
	data-sap-ui-libs="sap.m"
	data-sap-ui-theme="sap_bluecrystal"
	data-sap-ui-bindingSyntax="complex"
	data-sap-ui-compatVersion="edge"
	data-sap-ui-preload="async"
	data-sap-ui-resourceroots='{
		"your.app": "yourDir/"
}'>
Note

For more information on bootstrap attributes, see Bootstrapping: Loading and Initializing.

The most important setting here is data-sap-ui-preload="async". This enables the runtime to load the modules for all declared libraries asynchronously in the background. This reduces the amount of requests sent by the client that could block each other.

Don't forget to implement the asynchronous behavior in the init event of the core as well, as shown in the following code snippet:

<script>
sap.ui.getCore().attachInit(function() {
	sap.ui.require([
		"sap/ui/core/ComponentContainer"
	], function(ComponentContainer) {
		sap.ui.component({
			async: true,
			name: "your.component"
		}).then(function(yourComponent) {
			new ComponentContainer({
				component: yourComponent
			}).placeAt("content");
		});
	});
});
</script>
The async mode only pays out if all libraries that are required initially are specified in the data-sap-ui-libs attribute of the bootstrap. If there are additional dependencies that are not listed (like transitive dependencies that are inherited from a listed library), SAPUI5 can load them automatically, but then SAPUI5 has to read the configured libraries first and find out about these dependencies, which also takes time. That's why we recommend adding these libraries explicitly to the bootstrap parameter data-sap-ui-libs to achieve maximum parallelism.
Note

This does not apply for apps that have a descriptor file. In this case, only direct dependencies should be listed. For more information, see Descriptor for Applications, Components, and Libraries.

Network
If you want to quickly check the network load caused by your app, look at the developer tools of your browser, 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:
  • Synchronous requests that block each other

    In this case use the data-sap-ui-preload="async" setting in the bootstrap.

  • Amount of requests is too big

    For apps that use grunt as a Web server, you can use the openui5_preload task to bundle and minimize all relevant files of a component. For more information, see Optimizing OpenUI5/SAPUI5 AppsInformation published on SAP site in the SAPUI5 Developer Center on SAP SCN. This task creates a Component-preload file.

    If you're using SAP Web IDE, refer to Application Build in the SAP Web IDE documentation.

Code
You can also optimize your coding by doing the following:
  • Use non-blocking view loading as described here: Instantiating Views

  • If you make use of data binding with an OData service as a back end, you may also consider switching your OData model to our more modern V2 OData model. For more information, see OData V2 Model

  • Make use of asynchronous module loading (AMD style) for custom controls or other scripts. Although it is only supported by the preload, it will help us in future to enable asynchronous loading of individual modules combined with the usage of HTTP/2 or AMD-based packagers. It also ensures proper dependency tracking between modules.

    Writing AMD modules is only half the story. You only need to avoid access to SAPUI5 classes via global names. Do not use new sap.m.Button(), but require the Button and call the constructor via the local AMD reference. For more information, see the API Reference for sap.ui.define in the Demo Kit.

  • Avoid the usage of setTimeout() calls with values greater than 0. This usually indicates an anti-pattern in application code that is used as workaround and should be avoided. (See also JavaScript Code Issues: Don't use timeouts.)

  • Don't use visibility for lazy instantiation. (See Performance Issues: Don't use visibility for lazy instantiation.)