Measure First
Before touching code, measure. Open your app in Chrome DevTools, record the Network tab, and note the initial load time and the largest bundles. You can't tune what you haven't measured.
Most SAPUI5 performance problems come from loading too much, too early — not from slow JavaScript execution.
1–3: Load Less, Load Smarter
- Async bootstrap: use
data-sap-ui-async="true"anddata-sap-ui-preload="async"in your bootstrap script so modules load in parallel instead of sequentially. - Component preload: ship a
Component-preload.jsbuilt by UI5 Tooling. One bundled file beats hundreds of individual module requests. - Lazy-load views: don't load every view at startup. Load detail views on demand with
loadFragmentor lazy routing targets.
4–6: Tame Your Data
- Paging over $top: set sensible page sizes on tables and lists. Loading 10,000 rows "just in case" destroys initial render time.
- Growing lists: use
growing="true"withgrowingThresholdonsap.m.Listso rows render as the user scrolls. - Selective binding: bind only the properties you display. A heavy OData entity with 40 fields bound to a 5-column table wastes parsing time on every row.
A table with 25 rows and 6 visible columns should never request the full entity payload. Trim the $select clause and watch render times drop.
7–8: Cut Rendering Waste
- Suspend bindings during bulk changes: call
oModel.setSuspended(true), apply your changes, then resume. This avoids a re-render per change. - Avoid
binder.refresh()loops: never call refresh inside a binding change handler. You will trigger an infinite invalidation cycle.
oModel.setSuspended(true);
aItems.forEach(function (oItem) {
oModel.setProperty("/Items/" + i + "/Status", "X");
});
oModel.setSuspended(false);
The suspension batches all updates into a single re-render — the difference is dramatic with large models.
9–10: Polish the Edges
- Cache OData metadata: enable metadata caching (
useBatchanddisableHeadRequestForTokenwhere appropriate) to cut a round trip on every app start. - Compress and cache statically: serve your app through a CDN or reverse proxy with gzip and long cache headers for preload bundles.
- Defer non-critical controls: charts, maps, and rich text editors can initialize after the first paint. Render the core screen first, then load the heavy widgets.
Performance is a feature users feel but never praise — until it's gone. Build the measurement habit now and every future change gets faster to evaluate.
Wrapping Up
Apply these ten in order and re-measure after each batch. Say you have a requisition app that takes 12 seconds to load — async bootstrap plus Component preload alone often cuts that in half before you touch a single line of app code.
The biggest wins are almost always at the top of this list. Resist the urge to micro-optimize rendering before you've fixed the loading strategy — you will spend days for seconds.
Which of these made the biggest difference in your app? Let me know in the comments.