# SAPUI5 Performance Optimization **Source**: Official SAP SAPUI5 Documentation **Documentation**: [https://github.com/SAP-docs/sapui5/tree/main/docs/05_Developing_Apps](https://github.com/SAP-docs/sapui5/tree/main/docs/05_Developing_Apps) **Last Updated**: 2025-11-21 --- ## Core Loading Strategies ### 1. Asynchronous Loading (Critical) Always enable asynchronous loading for optimal performance. **Bootstrap Configuration**: ```html ``` **Component Interface**: ```javascript sap.ui.define([ "sap/ui/core/UIComponent" ], function(UIComponent) { "use strict"; return UIComponent.extend("my.app.Component", { interfaces: ["sap.ui.core.IAsyncContentCreation"], metadata: { manifest: "json" } }); }); ``` **Benefits**: - Non-blocking module loading - Parallel resource fetching - Faster initial load time - Better user experience --- ### 2. Manifest-First Approach Configure dependencies in manifest.json instead of bootstrap. **manifest.json**: ```json { "sap.ui5": { "dependencies": { "minUI5Version": "1.120.0", "libs": { "sap.m": {}, "sap.ui.core": {}, "sap.f": {} } } } } ``` **Benefits**: - Dependency reuse across contexts - Earlier rendering - Parallel loading optimization - Design-time tool support --- ### 3. Lazy Loading Libraries Load heavy libraries only when needed: **manifest.json**: ```json { "sap.ui5": { "dependencies": { "libs": { "sap.m": {}, "sap.ui.table": { "lazy": true } } } } } ``` **Load Before Use**: ```javascript sap.ui.require(["sap/ui/core/Lib"], function(Library) { Library.load({ name: "sap.ui.table" }).then(function() { // Library loaded, now create table }); }); ``` --- ## Resource Optimization ### 1. CDN Distribution Load SAPUI5 from CDN for better performance: ```html ``` **Benefits**: - Global CDN distribution (AKAMAI) - Reduced latency - Caching across applications - No server load --- ### 2. Component Preload Enable component preload to bundle resources: **Automatic** (UI5 Tooling): ```bash ui5 build ``` Creates `Component-preload.js` containing: - All views - All controllers - All fragments - manifest.json - i18n files **Load Component Preload**: ```javascript { "sap.ui5": { "dependencies": { "components": { "my.other.component": { "lazy": false // Preload enabled by default } } } } } ``` --- ### 3. Library Preloads Ensure library preloads are enabled (default): **Check Configuration**: ```javascript // Preloads enabled by default // Don't set data-sap-ui-preload="sync" (synchronous loading) ``` **Verify Preload Loading**: - Open Network tab in browser - Look for `library-preload.js` files - Should see ONE request per library, not many --- ### 4. i18n Configuration Prevent 404 errors for missing language files: **manifest.json**: ```json { "sap.ui5": { "models": { "i18n": { "type": "sap.ui.model.resource.ResourceModel", "settings": { "bundleName": "my.app.i18n.i18n", "supportedLocales": ["en", "de", "fr"], "fallbackLocale": "en" } } } } } ``` **File Structure**: ``` i18n/ ├── i18n.properties (fallback) ├── i18n_en.properties (English) ├── i18n_de.properties (German) └── i18n_fr.properties (French) ``` --- ## Code Optimization ### 1. Replace Deprecated jQuery Migrate from deprecated `jquery.sap.*` modules: **Before** (deprecated): ```javascript jQuery.sap.require("sap.m.MessageBox"); jQuery.sap.delayedCall(100, this, function() {}); ``` **After** (modern): ```javascript sap.ui.require(["sap/m/MessageBox"], function(MessageBox) {}); setTimeout(function() {}, 100); ``` **Migration Guide**: - `jQuery.sap.delayedCall` → `setTimeout` - `jQuery.sap.log` → `sap/base/Log` - `jQuery.sap.uid` → `sap/base/util/uid` - `jQuery.sap.getUriParameters` → `sap/base/util/UriParameters` --- ### 2. Asynchronous Factories Use async variants for better performance: **Components**: ```javascript // Old (sync) var oComponent = sap.ui.component({ name: "my.app" }); // New (async) sap.ui.require(["sap/ui/core/Component"], function(Component) { Component.create({ name: "my.app", manifest: true }).then(function(oComponent) { // Component ready }); }); ``` **Views**: ```javascript // Old (sync) var oView = sap.ui.view({ viewName: "my.app.view.Main", type: "XML" }); // New (async) sap.ui.require(["sap/ui/core/mvc/XMLView"], function(XMLView) { XMLView.create({ viewName: "my.app.view.Main" }).then(function(oView) { // View ready }); }); ``` **Controllers**: ```javascript // Controllers loaded automatically with views (async) ``` **Resource Bundles**: ```javascript // Old (sync) var oBundle = jQuery.sap.resources({ url: "i18n/i18n.properties" }); // New (async) sap.ui.require(["sap/base/i18n/ResourceBundle"], function(ResourceBundle) { ResourceBundle.create({ url: "i18n/i18n.properties", async: true }).then(function(oBundle) { // Bundle ready }); }); ``` --- ## Data Handling ### 1. OData Model Preload Enable metadata preloading: **manifest.json**: ```json { "sap.ui5": { "models": { "": { "dataSource": "mainService", "preload": true, "settings": { "defaultBindingMode": "TwoWay" } } } } } ``` **Benefits**: - Metadata loads during component init - Faster first data request - No metadata loading delay --- ### 2. Use $select for OData Fetch only needed properties: **Without $select** (bad): ```javascript // Fetches ALL properties this.getView().bindElement("/Products('123')"); ``` **With $select** (good): ```javascript // Fetches only specified properties this.getView().bindElement({ path: "/Products('123')", parameters: { select: "ProductID,Name,Price,Category" } }); ``` **In List/Table**: ```xml ``` **Benefits**: - Smaller payload - Faster backend queries - Reduced network transfer - Better performance --- ### 3. OData V4 Migration Prefer OData V4 over V2: **manifest.json**: ```json { "sap.app": { "dataSources": { "mainService": { "uri": "/odata/v4/catalog/", "type": "OData", "settings": { "odataVersion": "4.0" } } } }, "sap.ui5": { "models": { "": { "dataSource": "mainService", "settings": { "synchronizationMode": "None", "operationMode": "Server", "autoExpandSelect": true } } } } } ``` **Benefits**: - Better performance - Server-side operations - Automatic $expand and $select - Modern features --- ### 4. Batch Requests Combine multiple requests: **OData V2**: ```javascript var oModel = this.getView().getModel(); oModel.setUseBatch(true); oModel.setDeferredGroups(["changes"]); // Add to batch oModel.create("/Products", oData1, { groupId: "changes" }); oModel.create("/Products", oData2, { groupId: "changes" }); oModel.update("/Products('1')", oData3, { groupId: "changes" }); // Submit batch oModel.submitChanges({ groupId: "changes", success: function() { MessageToast.show("All changes saved"); } }); ``` **Benefits**: - Single HTTP request - Reduced network overhead - Better performance - Atomic operations --- ### 5. Metadata Caching Enable metadata caching for ABAP backends: **Automatic**: SAPUI5 uses cache tokens automatically **Check Network**: - Look for `sap-context-token` parameter - Metadata should load from cache on subsequent visits --- ## UI Control Performance ### 1. Table Selection Choose appropriate table control: **sap.m.Table** (Mobile/Responsive): - Good for: < 100 rows - Keeps all rows in DOM - Better for responsive layouts - Growing/scrolling support **sap.ui.table.Table** (Grid/Analytical): - Good for: 100+ rows - Virtual scrolling (only visible rows in DOM) - High performance for large datasets - Fixed column layout **Example**: ```xml ``` --- ### 2. Reduce Control Complexity Minimize controls in repeated aggregations: **Bad** (heavy): ```xml