I have been working as a Fiori application developer and nowadays I have read quite a lot of blogs which introduce how to build web application using React. React is an open-source JavaScript library providing a view for data rendered as HTML. You can find more information from Wikipedia and its source code from github.

Most of those blogs have mentioned that React has quite good performance but don’t contain detail performance data. Since I have been using SAP UI5 framework in my daily work, I am curious about the performance comparison between SAPUI5 and React regarding the topic of page rendering.

Comparison environment setup

I have implemented a most simple application separately via UI5 and React to measure their page rendering performance difference.
The application has the following appearance: it consists of a TextField with a given numbers of TextArea. The number of TextArea is controlled via code. Every time you type something in the TextField, the text you have typed will be written in all of the TextField as well.

The UI5 implementation

I use Json view to implement this application. The source code of “sample.view.js” has been listed below. The variable “_NUMBER” controls the number of TextAreas.

sap.ui.jsview("compareReact.sample", {
_NUMBER: 100,
_textAreas: [],
getControllerName : function() {
  return "compareReact.sample";
},
createContent : function(oController) {
  var that = this;
  var oInput1 = new sap.ui.commons.TextField('input1');
  oInput1.setValue("Hello!");
  oInput1.attachLiveChange(function(event){
   // console.log('Text changed to :'+ oInput1.getValue());
   for( var i = 0; i < that._NUMBER; i++){
     that._textAreas[i].setValue(event.getParameter("liveValue"));
   }
   }
  );
  this.oLayout = new sap.ui.layout.VerticalLayout("Layout1", {
          content:[oInput1]
        });
  for( var i = 0; i < this._NUMBER; i++){
   var oInput = new sap.ui.commons.TextArea('text' + i);
   this.oLayout.addContent(oInput);
   this._textAreas.push(oInput);
  }
  return this.oLayout;
}
});

The React implementation

For those who are not familiar with React, let me briefly introduce this source code:
When I studied React for the first time, I was confused by the “syntax error” for example in line 28 and 32~36. Actually this is the supported syntax on script tag with type “text/babel” ( in line 10 ). Using this JSX grammar, it is allowed to insert native HTML markup into JavaScript code.

And keep in mind, such JSX code will be translated to native JavaScript when the page is rendered, by browser.min.js. For steps how to get and debug converted JavaScript source code, please refer to my blog How to get and debug converted source code in React.

In line 12, a customized ReactComponent is created which encapsulates the logic how the view should be rendered and what is the data source of this view. For me, I would like to treat the function render() as createContent() in SAPUI5 Json view, andsetState() as the ClientModel handling in SAPUI5. You see the line 33 “value={value}” and shouldn’t this be the same logic as SAPUI5 data binding?

When there is live-change event occurred, the callback function “this.handleChange” specified in line 33 will be called, which will then trigger ReactComponent.setState and finally render() will be called to refresh the page.

The created ReactComponent could be used the same way as native HTML tag to insert into the page.

The code above has exactly the same logic as what we do in every UI5 application:

Use Chrome timeline to measure performance

I will use the tab “TimeLine” to measure performance. There is already a good article introducing how to use this tab by Google.

UI5 application result

I start comparison by specifying the number of TextArea as 100. First start UI5 application. I type “3” for six times and I get the following measurement result:

(1) The six areas marked with black bold underline represent the performance data for each of the six “3” type action. As I only focus on rendering stuff, I can ignore the orange color for “Scripting”. So the total rendering time for scenario with 100 TextArea are 36.3ms and Painting time is 6.9ms.

You might be confused by the terms “layouting”, “rendering” and “painting”? Read this awesome blog How browsers work-Behind the scenes of modern web browsers to understand their exactly meaning.

And have you noticed the small red icon for “Long frame”?

You can click the hyperlink “jank” to know more detail about “Long frame“.

By clicking the corresponding rectangle with different color, you can get a detail view under tab “Event Log”.

For example, below detail view shows that the code in line 416 of TextField.js:formatted has triggered the style recalculation which consumes 1.8ms.

Click the hyperlink and we are eable to see the exact line with its context. In this case, we first get the native HTML DOM node in line 399 and fill its attribute value in line 416 with the character we have typed.

And how is this 36 FPS ( frame per second ) calculated? 36 FPS = 1 / 27.7ms * 1000, means 36 frames per second.

According to Google documentation, “Each of those frames has a budget of just over 16 ms (1 second / 60 = 16.66 ms). In reality, however, the browser has housekeeping work to do, so all of your work needs to be completed inside 10 ms. When you fail to meet this budget the frame rate drops, and the content judders on screen. This is often referred to as jank, and it negatively impacts the user’s experience.“, this is the reason why this frame with duration 27.7 ms is marked with red indicator for “Long frame”.

React application result

We can easily find that there is no Long frame for the six frames rendered in React, total rendering time is 19.5 ms ( while UI5 is 36.3 ms ) and painting time 5.4 ms ( UI5 6.9 ms ).

React has much better performance than UI5 ( 63 FPS vs 36 FPS ).

Actually there is no apparent difference between UI5 and React on Layouting; The bottleneck for UI5 lays in the T.setValue which consumes the 46.2% of total time.

In React, the code to change the native HTML node value, setTextContent in react.js:16904, only consumes 0.6ms.

The pixel pipeline

As documented by Google, “Most devices today refresh their screens 60 times a second. If there’s an animation or transition running, or the user is scrolling the pages, the browser needs to match the device’s refresh rate and put up 1 new picture, or frame, for each of those screen refreshes. Each of those frames has a budget of just over 16 ms (1 second / 60 = 16.66 ms). In reality, however, the browser has housekeeping work to do, so all of your work needs to be completed inside 10 ms. “

That is to say, for any frame, it is better to avoid the total duration of the five mentioned steps ( 1. JavaScript 2. Style calculation 3. Layout 4. Paint 5. Composite ) not exceed 10 ms.

要获取更多Jerry的原创文章,请关注公众号"汪子熙":


注销
1k 声望1.6k 粉丝

invalid