Skip to Content
Technical Articles

UI5ers Buzz #52: The Rendering Evolution: Semantic Rendering and CSS Variables

Introduction

The evolution of the UI5 Framework is a mammoth task. We fight on various fronts to modernize the framework, to improve the performance, to increase the development experience and to move closer to web standards. Besides the evolution of the Modular Core and the Tooling we also innovate the area of Rendering and Controls. In this area we work on the UI5 Web Components, the Semantic Rendering and the CSS Variables. We call this the Rendering Evolution.

UI5 Web Components

With UI5 Web Components, we move the implementation of the UI elements into the web standards layer and the runtime into the browser. This brings a lot of advantages from performance perspective (a UI elements framework with a footprint of 0kB) and it comes with better interoperability so that our UI elements can be shared with any UI framework. In the near future, we will integrate back the UI5 Web Components in the UI5 Framework. The idea is to use the UI5 Controls as wrappers to connect the UI5 Web Components with the frameworks’ lifecycle and programming model features like the data binding and the integration into the XMLView. All this is explained in more depth in the blog post: “UI5 Framework and UI5 Web Components”. For a smooth integration of UI5 Web Components into the UI5 Framework we require the following enhancements: Semantic Rendering and CSS Variables.

Semantic Rendering

Semantic Rendering is changing the way how the rendering engine of the UI5 Framework works. In 2009, we started with string-based rendering which was the fastest option at that point in time. 11 years later, the browser stack has evolved, the DOM APIs are harmonized, and its performance is quite good. In our experience over the last years, we also noticed that many UI5 Controls which need to optimize their rendering have to implement custom setters to patch their DOM manually to increase the update performance. This leads to additional code which also comes with a dedicated price-tag.

Therefore, we decided to enhance the rendering engine to support DOM patching out-of-the-box. The initial rendering will still be string-based but all updates will be applied by patching the DOM. This allows us to get rid of the custom setters to really reduce code which is also a potential place for issues as the custom setters and the renderers have to be kept in sync. Changes to the state of the UI5 Controls will be automatically applied via DOM patching and thus the custom setters are not needed anymore. Unfortunately, this doesn’t come for free. While we have enhanced the rendering engine internally, we needed to introduce a new UI5 Control Renderer API. This API needs to provide more semantics to the rendering engine and that is the reason why we call this solution Semantic Rendering. The new API is an incremental DOM-like API and the renderer need to be flagged with the attribute apiVersion: 2.

Let’s compare a simple UI5 Control written previously with a classic string-based API:

var Square = Control.extend("my.Square", {

	metadata : {
		properties : {
			"text" : "string",
			"size" : { type: "sap.ui.core.CSSSize", defaultValue: "200px" }
		}
	},

	renderer : {
		render : function(oRm, oControl) {
			oRm.write("<div");
			oRm.writeControlData(oControl);
			oRm.addStyle("width", oControl.getSize());
			oRm.addStyle("height", oControl.getSize());
			oRm.writeStyles();
			oRm.addClass("mySquare");
			oRm.writeClasses();
			oRm.write(">");
			oRm.writeEscaped(oControl.getText());
			oRm.write("</div>");
		}
	}

});

With the refactored one written with the new incremental DOM-like API (apiVersion: 2):

var Square = Control.extend("my.Square", {

	metadata : {
		properties : {
			"text" : "string",
			"size" : { type: "sap.ui.core.CSSSize", defaultValue: "200px" }
		}
	},

	renderer : {
		apiVersion : 2,
		render : function(oRm, oControl) {
			oRm.openStart("div", oControl);
			oRm.style("width", oControl.getSize());
			oRm.style("height", oControl.getSize());
			oRm.class("mySquare");
			oRm.openEnd();
			oRm.text(oControl.getText());
			oRm.close("div");
		}
	},

});

As you can see, the incremental DOM-like API is shorter than the classic string-based API and provides more context to the render manager. There have been several enhancements: writing the control data is not required anymore as it happens as part of the openStart, write styles and classes can be omitted as the openEnd takes care to append them and the text doesn’t need to be escaped anymore as the new API automatically escapes the content. The following table compares the two renderer implementations side-by-side:

A special feature of the Semantic Rendering is the co-existence of the renderers based on the old and the new API. The following picture illustrates a control tree with V2 renderers (new API) and the V1 renderers (old API):

While a change of the state of a control using a V2 renderer (dashed border and colored background) only invalidates and updates the DOM of the control, a change to the state of a control using a V1 renderer will also re-render all child controls regardless whether they support DOM patching or not. This should make it clear why it is so important to migrate to V2 renderers. In the UI5 codebase we are step-by-step migrating to V2 renderers. Major and fundamental controls have already been migrated in order to benefit from DOM-patching and to reduce the amount of code by removing the custom setters. We continue to work on this transition to reach a good coverage of migrated controls.

The Semantic Rendering is available since UI5 1.67. More information about the Semantic Rendering can be found in the API documentation of the sap.ui.core.RenderManager or presented by our expert Cahit Guerguec at the UI5con 2019 in the session: Rendering Evolution.

CSS Variables

The CSS Variables are the link to enable theming for different UI technologies based on web standards. Right now, we extend the UI5 Web Components and the UI5 Framework to make use of the CSS Variables provided by the UI theme designer. The UI theme designer, the UI5 Framework and also the UI5 Web Components are based on the so-called theming base content which provides all the relevant theming parameters as CSS Variables. The UI theme designer is used by customers to manipulate the theming parameters to create their custom theme. Still today, a change of the theme parameters requires a theme build which generates the CSS files. To overcome that build, in future just the CSS Variables will be generated and used by the UI5 Web Components and the UI5 Framework.

UI5 Web Components and CSS Variables

The latest version of the UI5 Web Components already consumes the theming base content. This enables the Web Components to just refers to the CSS Variables in their CSS. When the UI5 Web Components are switching the theme, it is sufficient to just exchange the CSS Variables.

UI5 Framework and CSS Variables

The UI5 Framework has an experimental support for CSS Variables. The generated CSS of the UI5 Framework is based on the theming parameters of the theming-base-content. But instead of CSS Variables it consumes the theming parameters as Less variables which can only be used during the theme build. Since UI5 1.76, the theme build can also produce CSS Variables which can be used for custom theming (e.g. of custom controls – a long missing feature!).

Experimental Flag to play around with CSS Variables

The experimental flag is called data-sap-ui-xx-cssVariables and can have the values false|true|additional. When enabling the CSS Variables with the value true then the UI5 Framework embeds per library the CSS Variables file and a so-called skeleton CSS file which has placeholders for the CSS Variables. This feature is highly experimental. A safer but also experimental variant is the option additional. The UI5 Framework will now embed the CSS Variables per library next to the standard library CSS files. But now, these CSS Variables can be used by custom controls and/or by UI5 Web Components.

Assuming our custom control above, the my.Square which has the class mySquare can benefit from the CSS variables in the following way:

.mySquare {
	display: inline-block;
	border: 1px solid var(--sapTextColor);
	background-color: var(--sapBrandColor);
}

The syntax var(–variableName); now allows to easily access the CSS variables and custom controls will automatically become theme-aware. Unfortunately, this is not supported in IE11 in the UI5 Framework whereas the UI5 Web Components are supporting IE11 by using a ponyfill.

The CSS Variables are the way forward in the area of Rendering and Controls to support the visual harmonization and to introduce a common theming dependency for UI5 Web Components, the UI5 framework and even other technologies. In addition, it enables theming for custom controls and is supported by all modern browsers.

Conclusion

The Rendering Evolution is focusing on performance and harmonization. It is the key to connect the UI5 Web Components and the UI5 Framework. The CSS Variables will help to harmonize the visual appearance, especially when using both technologies together so that they finally can melt together. Also, we are moving closer to web standards to benefit from the evolution of the web stack. It improves the side-by-side usage of the UI5 Framework with other web frameworks and especially the UI5 Web Components. We still have plenty ideas and will continue on the evolution of our Rendering and Controls area. More to come, stay tuned…

 

Previous Post: UI5ers Buzz #51: UI5 Tooling 2.0: How to develop and run SAP Fiori elements locally!

 

Peter is one of the initiators who started the Phoenix project (a.k.a. OpenUI5/SAPUI5) grown into the role of the UI5 Chief Architect mainly focusing on UI innovation in the area of the UI framework (UI5 Evolution), controls (UI5 Web Components), tooling (UI5 Tooling). 

 

 

 

2 Comments
You must be Logged on to comment or reply to a post.