This is the second article in a series of in-depth studies of SAP UI5 framework code.
Series directory
- SAP UI5 application developers understand the meaning of UI5 framework code
- UI5 Module lazy loading mechanism
- UI5 control rendering mechanism
- HTML native events VS SAP UI5 Semantic events
- UI5 control metadata implementation details
- Instance data implementation details for UI5 controls
- UI5 control data binding implementation principle
- Three data binding modes of UI5 control: One Way, Two Way and OneTime
- UI5 control ID generation logic
- UI5 controls multiple languages (Internationalization, the Internationalization, i18n) support the implementation of the principle
- The Button control in the XML view
- The Button control and the DOM element behind it
Using Jerry’s previous article, a scaffolding application for SAP UI5 learning, without any background API dependencies introduced to the scaffolding application, create a UI5 application that contains only a Button control:
Opened in the browser, 18 requests were triggered, network traffic was 1.1MB, and the page loaded 5.1MB of resources (see the purple box at the bottom of the image below).
By the way, why is the size of the resource loaded on the page (5.1 MB) larger than the amount of data transferred over the network (1.1 MB)?
There is a saying on the Internet that a page load is the sum of the resources loaded through the network and the resources read from the browser cache. Therefore, the size of the page load displayed in the Chrome developer tool is greater than the amount of data transferred over the network.
This is not entirely true. More precisely, the page load resource statistics is the front-end page load of all resources, after decompression of the original size.
Turn on the Use Large Request Rows option in Chrome Developer Tools to display the original size of the network-loaded resource after decompression, as shown below:
These instructions from Google’s official website: developers.google.com/web/tools/c…
Back to our UI5 application, Ctrl+Alt+Shift+P, select “Use Debu Sources” and make SAP UI5 load the debug version library file:
After button appears on the page, open Chrome Developer Tools Sources and see a Commons folder under SAP/UI:
Recall that in our scaffolding application code, we created a new instance of the Button control in the sap.ui.commons namespace:
So at runtime, the Button Module corresponding to SAP UI5 will be loaded. Button-dgb.js is responsible for Button lifecycle management and event response, and buttonRenderer-Dgb.js is responsible for rendering Button instances into native HTML code.
Switch to the Network TAB page, select any Network request loaded by Button Module, hover the mouse to the Initiator column, in the popup window you can see a call stack, from which you can observe that index. HTML is the consumer of Button control. Trigger the loading of both Button Modules.
Set a breakpoint at the code that instantiates the Button control in index.html and refresh the application. Sap.ui.mons.Button is not a native HTML element, so the debugger steps up to line 11 and triggers the Button Module to load:
This is the lazy loading mechanism of SAP UI5 Module: if the page does not use a Button control, the corresponding Button Module will never be loaded.
The lazy stub for XXX is used to load the Button Module on line 26384.
RequireModule is ready to load the Module file SAP/UI/Commons /button.js:
When the Module file is loaded via AJAX, SAP UI5 gets just plain string text, and you can’t use it to create a Button instance directly. SAP UI5 calls the browser’s native API, window.eval(), passing the string contents of the button.js file into the API. The result is a JavaScript object that is the runtime entity of SAP UI5 button Module.
SAP UI5 runtime maintains a registry for all modules, storing information about these modules in a key-value pair data structure of type String. The value type is the JavaScript object returned by window.eval() after executing the loaded JavaScript file contents.
Module can be in a series of enumerated states: INITIAL, LOADED, READY, FAILED, PRELOADED.
Going back to my example, since my code triggered the first load of the Button Module, line 16487 marks the status of the Module as INITIAL.
Continue debugging:
- Line 16514: Set the Button Module state to LOADING.
- Line 16517: Load the normal or debug version of the Button Module based on the value of the global flag window. sap-uI-loaddbg.
- Line 16520: Gets the URL of the Module to be loaded based on the Module name.
- Line 16525: Load button-dgb.js with jquery.ajax.
The new sap.ui.mons.button in our code cannot continue until the Module is loaded, so AJAX calls are made in synchronous mode (async = false). In its successfully LOADED callback function, the Module state is set to LOADED, and the response variable contains the text content of button-Dgg.js.
The status of Module is LOADED, indicating that its text content has been LOADED and is ready to be executed by execModule on line 16543 (note the IF condition).
The sScript variable contains the text content of button-dgg.js. After window.eval() is executed, the Module state is set to READY:
The new sap.ui.commons.button statement seems to be just a simple instance construction operation, but behind it hides the idea of SAP UI5 control design.
Create a new empty Button instance oInstance with the factory method. Then enrich oInstance with the parameters passed in when the consumer calls new sap.ui.mons.button:
We look at the source code of the Button Module and find that the prototype of the Button is Control:
SAP UI. Core.Control
- Rendering: Each SAP UI5 control has a Renderer that is called by the RenderManager to generate native HTML code.
- Show/hide, Busy Indicator, support associated with custom CSS style classes, register browser events.
The prototype for Control is Element:
Element is the base Element of THE SAP UI5 page and is used primarily for the internal implementation of UI5.
The prototype for Element is ManagedObject:
Jerry won’t take a screenshot of this because it’s too long. Just remember the conclusion: Start with a Button control and work your way up its prototype chain to a BaseObject(the equivalent of Object in ABAP/Java).
Button->Control->Element->ManagedObject->EventProvider->BaseObject.
Therefore, the constructors for each node in the Button’s prototype chain are executed one at a time before executing the Button’s own constructor:
Next article in this series: UI5 control rendering mechanisms.
Thanks for reading.
More of Jerry’s original articles can be found in “Wang Zixi” :