Technical Articles
UI5 Rendering: The Next Big Step Towards a Better Performance
In UI5, the rendering process involves creating the visual representation of user interface elements, and it can be a resource-intensive task, especially when dealing with complex and responsive UIs. Our performance tests show that the rendering process is one of the most significant factors affecting the performance of UI5 applications. Hence UI5 has introduced various features to improve the rendering and re-rendering process, for example Semantic Rendering.
In the latest release of UI5, there is an innovation in rendering that promises to improve the performance further with reducing the number of redundant re-rerenderings.
To understand this innovation let’s have a look at first how the rendering works in UI5. By default, if a property, an aggregation, or an association of a control is changed, then the control gets invalidated, and the re-rendering process for that control and all its descendant controls start. That means child controls re-render together with their parent even though there is no DOM update necessary.
The new rendering reuses the control’s DOM output and prevents child controls from unnecessary re-renderings while they are getting rendered by their parent.
To activate the new rendering, the “apiVersion” property of the control renderer must be set to 4. This new marker lets the RenderManager know that a control’s output is not affected by changes in the parent control. Of course, this is only possible if there is a good rendering encapsulation and no parent state dependency.
For example, let’s say you have a parent control called “ParentControl” that has a child control called “ChildControl”. ChildControl has its own properties, aggregations, and associations, and its output is only affected by them. By setting the apiVersion to 4 in the renderer of ChildControl whenever a property of the ParentControl is changed during the rerendering process, the RenderManager will check the apiVersion marker of the ChildControl’s renderer. If it’s 4, the RenderManager skips the rendering of the ChildControl, leading to faster performance and a smoother user experience.
However, to ensure compatibility with the apiVersion 4 marker, certain prerequisites must be fulfilled. First, all the prerequisites of the apiVersion 2 marker must be fulfilled by the control. Most importantly, the control renderer must maintain a proper rendering encapsulation and render only the properties, aggregations, and associations that are specific to the control. The renderer should not reference or depend on any state of the parent control or any other external element.
Please note that there is no apiVersion 4 control available in UI5 now. This will be done step by step in up-coming releases, but you would like to see some results, wouldn’t you? Then let’s start to build a few custom controls, once with apiVersion 2 and once with apiVersion 4. In my testing scenario I would like to stress the RenderManager, and I will first insert 1000 list items to the list and then change only the header of my list control. To measure the results, we need to know the frame rendering stats, and Chrome developer tools already have exactly what we need. To open the frame rendering stats, open the Rendering tab and enable the Frame rendering stats checkbox, then look at the statistics in the top corner of the page.
Now is the time… Here is the apiVersion 2 and here is the apiVersion 4 test case. Please note that the only difference between these tests is the apiVersion marker. If you do not want to hear noises from your computer’s fan, here are the test results we get.
If you now want to convert your custom controls to apiVersion 4, then please make sure that you fulfill the apiVersion 4 prerequisites. Here you can find the apiVersion 4 contract.
We are excited to see the impact that the apiVersion 4 marker will have on UI5 performance.
Nice!
I'm actually building a new custom control in 1.96.16 by rendering an embedded iframe (third-party ui based on sap data) inside a UI5 HTML-Control because of re-renderings after new odata binding (.bindItems()).
Now we use json model with supress invalidate (do not re-render after property change) and communicate the need of ui refresh over Postmessage API to the iframe. The webapp inside the iframe handles the partial ui re-rendering.
Best regards
Recep Subasoglu
What you are doing to handle a third-party ui makes perfectly sense to me but what we are trying to achieve with the apiVersion=4 is avoiding the re-rendering of the HTML control when a descendent of that HTML control is invalidated.
I must also point out that the HTML control with preferDom=true property has a special DOM handling and even though the parent of HTML control re-renders the HTML control puts its DOM output to a special preserved area during the re-rendering. This allows a stable DOM state for HTML control. This is especially important for iframes or canvases. But one day if we can support apiVersion=4 for all controls then we do not need such workarounds in the HTML control or you as an application developer do not need to call protected APIs with bSuppressInvalidate=true parameter. You just call the public APIs which invalidate controls but the RenderManager takes care of optimized DOM update. Basically nobody needs to think about the invalidation.
Nice update!
I couldn't help but wonder about couple of points in the contracts however. Any clarification on them is therefore greatly appreciated.
Does this mean that custom controls with custom events should deregister all handlers in the mentioned hooks? What is meant by 'proper deregistration` exactly? AFAIK 'event listener deregistration' is not mentioned in the custom control development docs.
"any other external element" can be interpreted rather vaguely. Many npm packages offer custom UI elements; writing UI5 control wrappers around them is great thing for the framework IMO as it enriches it with OSS stuff. If however an exported npm object is considered "external element" and no DOM manipulations can be done in the
onBeforeRendering
hook, how could such control profit from thev4
contract?Additionally, for which versions of the framework is the
v4
contract available? Specifically is it available forv1.108
which is LTM?It could well be that I am missing something from the docs, so if that's the case - sorry!
Thanks in advance for any info & BR.
Custom event (de)registration is mentioned here in the 5th bullet point. Basically, if you register an event in the onAfterRendering hook and do not clean it up in the onBeforeRendering hook then in every re-rendering the same event will be registered again and again since the apiVersion=2 rendering does in-place DOM patching and reuses the existing DOM of the control.
The apiVersion=4 works well if controls do not break the locality but sometimes this cannot be avoided. This is explained in the last bullet point of the apiVersion=4 contract Basically if a control state depends on a state of another component then the invalidation must be done for the dependent control when the state of the other component is changed. For example, if we insert a new list item to the List control then we do not need to visit the renderer of existing list items that means we can use apiVersion=4 for the List and list items but if the selectionMode property of the List control is changed then all list items must be invalidated by the List control so that list items render their single or multi selection (RadioButton/CheckBox) control. So the invalidation is the key for dependent states.
The apiVersion=4 optimization is available for the UI5 version 1.112 but as mentioned there is no standard UI5 control that supports apiVersion=4 yet.