React vs Angular: Slow rendering with React - angularjs

I was doing a comparison of Angular and React and decided to try out a performance test to see how fast a large(ish) list would render in both frameworks.
When I got done with my React prototype with some basic currency formating, it was taking ~2 seconds to render on my fast laptop. With Angular it was barely noticeable -- only when I switched to my phone did it have a noticeable lag.
This was very surprising because I was told that React was supposed to beat the pants off of Angular for performance, but it appears that the opposite is true in this case.
I distilled my prototype down to a very simple app to try to isolate the issue: https://github.com/pselden/react-render-test
In this sample, it's taking almost 200ms to render this simple list after changing the language, and I'm barely doing anything.
Am I doing something wrong here?
/** #jsx React.DOM */
'use strict';
var React = require('react'),
Numbers = require('./Numbers');
var numbers = []
for(var i = 0; i < 2000; ++i){
numbers.push(i);
}
var App = React.createClass({
getInitialState: function() {
return { locale: 'en-US' };
},
_onChangeLocale: function(event) {
this.setState({locale: event.target.value});
},
render: function() {
var currentLocale = this.state.locale;
return (
<div>
<select
onChange={this._onChangeLocale}>
<option value="en-US">English</option>
<option value="fr-FR">French</option>
</select>
<Numbers numbers={numbers} locales={[currentLocale]} />
</div>
);
}
});
module.exports = App;
/** #jsx React.DOM */
'use strict';
var React = require('react'),
ReactIntlMixin = require('react-intl');
var Numbers = React.createClass({
mixins: [ReactIntlMixin],
getInitialState: function() {
return {
numbers: this.props.numbers
};
},
render: function() {
var self = this;
var list = this.state.numbers.map(function(number){
return <li key={number}>{number} - {self.formatNumber(number, {style: 'currency', currency: 'USD'})}</li>
});
return <ul>{list}</ul>;
}
});
module.exports = Numbers;
PS: Added an angular version: https://github.com/pselden/angular-render-test
Edit: I opened an issue with react-intl and we investigated and found that there was not that much overhead with using https://github.com/yahoo/react-intl/issues/27 -- it's simply React itself that is slower here.

This is definitely an interesting test case.
If you take a look at the timelines, you can see that Angular is finished handling the change event in a mere 20ms. The remainder of the time is spent in layout and repaint.
React (using a production build, your repo uses dev by default) takes about 59ms. Again, the rest of the time is spent in layout and repaint.
If you take a look at the CPU flame charts, you can see that Angular appears to be doing a lot less work.
Angular:
React:
React provides a pretty good optimization hook in the form of shouldComponentUpdate that is especially useful when a single instance of a component out of thousands should update and the others should stay the same; it's a technique I use in this demo (try it out in an incognito window; I've found some Chrome extensions make layout/repaint times much higher—for me, adding/removing single elements once the list is 1000 long takes ~13ms, changing the size/color of an element takes ~1ms). However, it does no good when every element needs to update.
My guess is that Angular will be faster at changing most or all of the elements in your table, and React will be quite proficient at updating select entries when using shouldComponentUpdate.

I'm surprised nobody mentioned PureRenderMixin. It implements shouldComponentUpdate so you don't have to worry about it.
Also, I wonder if React Performance Tools would turn up something useful?
And I'm surprised to hear Angular is faster than React after watching this talk from Ryan Florence.

We have tried to analyze some of the attributes of our frameworks, of course, this is not the whole list. Below there is a table of consolidated and important, in our opinion, of comparing attributes.
Let’s get some more details:
Although Angular vs React differences are many, they can do the same thing, namely to build client interface. Both have their place. For those peoples who like web development above all interesting is innovative AngularJS approach to HTML.
AngularJS really is a full framework and not just a library, as the ReactJS, but ReactJS has better performance than the AngularJS by implementing virtual DOM. In our opinion, you should use AngularJS if:
you plan to carry a lot of unit tests during development,
you want a comprehensive solution for your application.
However, two-way data binding is often touted advantage of using AngularJS, but because it is implemented through a series digest, adding too much complexity for certain functions and expressions can lead to deterioration in performance of your applications.

In this particular case you need to be aware that the state trickles down and so do the DOM updates. What you want to do is create a Price component that stores the locale in its own state and receives a signal (ie channel or flux) to change the locale as opposed to sending the locale prop all the way down. The idea is that you don't need to update the entire Numbers component, just the prices inside. The component might look like:
var Price = React.createClass({
mixins: [ReactIntlMixin],
componentDidMount: function() {
subscribeToLocal(this.onLocaleChange);
},
onLocaleChange: function(newLocales) {
this.setState({locales: newLocales});
},
render: function() {
return <span>this.formatNumber(this.props.number, this.state.locales, {style: 'currency', currency: 'USD'})</span>
}
});

In React component, once you call setState, it will trigger the render function immediately. React will mark this component as dirty, and will re-render all the children element inside this component.
It will not render the whole Native DOM elements because of the Virtual DOM, thus it will still create new instances of its children ReactElements, which can lead to extra Javascript memory cost.
To avoid this issue, you need shouldComponentUpdate function which implemented in Component Class. it will executed before Render method. If you find the there is nothing changed right now, for instance in your example, you change the state.locale. You can definitely consider this component need no update. so just return false to prevent the render call.
This is a base solution to solve React performance issues. Try to add "shoudlComponentUpdate" in your Numbers Component to avoid tons of element re-render

This is an example where all that is changing is one data output. It's not impossible that Angular's two way data-binding simply offers a faster re-render when all that is changing is the display of the bound data.
React does not promise that its renders are faster than any other framework under all circumstances. What it does offer is the ability to handle ~arbitrarily complex DOM updates in very efficient manner, and offer a variety of lifecycle methods (e.g. componentWillReceiveProps, componentDidUpdate, in addition to the afore-mentioned shouldComponentUpdate) to let you fire callbacks on those events and control how and if they should happen. Here, there's very little to optimize, because all you are doing is changing 2,000 text displays.
edit: To clarify, React is useful in doing more complex DOM manipulations because it's virtual DOM algorithm allows it to choose the minimal set of DOM operations necessary to update your DOM. That's still a lot of work to do when all that needs to be happening is 2000 instances of some text changing.

Related

I want to use transition effects in react app. What type/ library for animation in react app should I use according to the latest trend?

I want to use some transition effects in my react js app. I am using function components in my app.
How do I include transition effects in app according to the business requirement these days?
I want to use animation such that on every render I can see the effect. It would be great if someone can help me out with an example.
If you want to use a library, I would suggest react-spring
https://react-spring.io/ it is based on spring physics, If you want to read about that more check this out https://www.joshwcomeau.com/animation/a-friendly-introduction-to-spring-physics/
And there is also another good option which is framer motion https://www.framer.com/motion/ which apparently offers more possibilities maybe out of the box (I personally have never tried it before)
For examples you can check their websites they have good examples.
I'm not sure what effect you are trying to generate.
css can be used by itself to generate animations or transitions.
You want to see the effect on each render?
i.e. You want to tie the effect to the react render cycle?
non-memoized values will change on every render
You could use a simple statement like const trigger = {};
Then react to trigger with a useEffect
useEffect(() => { do something }, [trigger]);
finally, visual effect.. apply a class based on state and use setTimeout to remove the state (and therefore the class)
This could be overly involved for exactly what you are trying to achieve but this works for all possible flows based on the question.
Here is one example with div element is moving to according vertical scroll position .
Look carefully.
First, Set the position using useState and define the window.onscroll function.
const [cardTop, setCardTop] = useState(0);
window.onscroll = function() {
if (window.pageYOffset < 30) {
setCardTop(window.pageYOffset + 'px');
}
};
Second, Set the style's top as state variable.
<div className='card t-card' id='tCard' style={{top:`${cardTop}`}}> ...
Congratulations. It probably act exactly.
It's similar to use Jquery or another Javascript, Only use state variable.
Thanks.

React redux oop classes

coming from angular i used to have a class for every entity in my DB, such class encapsulated all entity behaviour.
for example users Class can look like
export class User{
static notValid(u){
return !!((u.id && u.id > 0 && u.fullname && u.fullname.length > 2 && u.picture) === false);
}
static fromArray(arr){
let pack = [];
for(let i=0;i<arr.length;i++){
pack.push(new User(arr[i]));
}
return pack;
}
constructor(u){
this.id = u.id || 0;
this.fullname = u.fullname+'' || 'N/A';
this.picture = u.picture+'' || '/imgs/logo.png';
this.role = u.role || 'N/A';
this.username = u.username+'' || '';
this.email = u.email+'' || '';
this.dob = u.dob || 0;
this.gender = u.gender+'' || '';
///START SETTING FLAGS AND VALIDATING DATA;
this.isValid = !User.notValid(this);
this.saved = this.id > 0;
let n = this.fullname;
this.nickname = n.split(' ').shift()+' '+n.split(' ').pop();
}
save(){
///IF NO ID, POST TO SERVER
if(!this.saved)return $http.post('/user',this.toJson);
return $http.put('user/'+this.id,this.toJson());
//tojson is defined in prototype;
}
identity(){
return {id:this.id,fullname:this.fullname,picture:this.picture,nickname:this.nickname};
}
}
}
so that my controller doenot know about how to save or update User, all it have is to trigger save() on user object.
Now React world, where every thing inside app is a component;
1. how can i replicate such approach inside react component ?
i read alot that there is presentational components and smart components. but what about Data Model component ?
2. if i port all my current class's to react should i also implement render method ? can i have multiple render functions to return different html based on page.
example above User can appear inside Profile will all details, and as a card in users list, so i should keep html for both inside class prototype ?
You seem to be a bit confused about React and what it is designed to do which is perfectly normal, coming from the Angular world.
The thing is, as far as React is concerned there is no such thing as a data model, only components. These components can have state (or they may not) and these components are rendered to the DOM.
Various types of components seem to have confused you as well. React is only concerned with how data is presented. Presentation and container components are distinguished from each other to make it easier for us to reason about how to manage application state.
To answer your specific questions:
1) If you are really adamant about keeping your existing structure and make it work with React, you don't actually need to do a lot of work. Your data model components are just JavaScript objects. You can pass them around and you can give them to components. When some event happens in the components, you can call the relevant methods in your objects. You will need to make sure that Angular specific methods are ported to pure JavaScript though.
I advise against this approach. It will work at first but you will find yourself in a maintenance hell in no time. Believe me, I'm building large scale React apps in my job and I have been bitten by similar decisions when I first started writing React components.
2) Certainly you could add a couple of React methods to your class definitions and also throw in the presentation code (that is, HTML) and presentation state. Then you would be able to render these components.
But that really is not the way to go about it. React doesn't decide on anything for you whereas Angular is very opinionated about this. First and foremost you should follow some tutorials on React. Looks like you have a sizable application in your hands, so I would advise you to look into Flux and Redux as well.
After that you should sit down and design how your application should work and how your state should look. After that it will be a breeze to go through the actual coding part.
You can NOT have multiple render methods in a React component, that makes absolutely no sense. React is pure JavaScript and JavaScript doesn't have any concept of overriding class members in the sense of classical OOP. Heck, JavaScript doesn't even have the concept of a class, that has been included in ES6 so people coming from class oriented programming languages wouldn't need to properly learn how the prototype chain works.
React components, and JavaScript objects in general, can only have one key. You can try this in your browser's console.
let a = {b: 1, b: 2};
console.log(a);
The object a will only have one b key and the value for that key will be 2.
Having said all this, you can delegate the actual rendering of a component to other objects based on some conditions using normal JavaScript coding methods. But this isn't how React is supposed to work. Your render method can be able to decide on what to render based on your conditions.
First of all, let me tell you that I can't answer your question.
It looks like you're new to React. I've never used this approach to create a class for every entity in DB, in React, ever. It's new to me. Maybe it works, maybe it doesn't. But what I'd suggest you is to get your hands dirty first with example projects in react. That'll answer most of your questions.
However, I can answer some of your questions-
Data Model component ?
Obviously, there is no such thing as Data Model component. React is all about unidirectional data flow. You want to use redux for state management in react. The components which are connected to this state are connected/smart components. Smart components pass the state to presentational/dumb components via props (properties). So there is that. All of the state comes from Redux or similar state management mechanism viz. Flux.
can i have multiple render functions to return different html based on
page.
No. One component contains only one render() method. That is precisely why I suggest you to please build some example apps in React.
If you want to learn React, here's what I'd recommend you, in that particular order-
React.js
Redux
Redux-thunk
Redux-saga
React is not a monolithic framework like Angular. It's just a library. And programmers are meant to throw different libraries together to build their apps.

Re-rendering an app using ReactDOM.render() rather than within its container component -- anti-pattern?

I have a single object state-driven application whose state dispatch/subscribe logic is to be kept separate from the React 'flow' (i.e. no helpers like React-Redux bindings).
When the state changes, my app re-renders.
Is there any difference between the following two implementations, or any anti-pattern concerns? (sorry to anyone upset I'm not using JSX)
var myElementClass = React.createClass(
render : function() {
//make use of this.props.state...
}
);
var myAppContainerComponent = React.createElement(
myElementClass,
{state : dataStore.getState()}
);
dataStore.onChange(function(){
ReactDOM.render(myAppContainerComponent, someDOMContainer);
});
vs...
var myElementClass = React.createClass(
componentDidMount : function() {
var self = this;
this.props.store.onChange(function(){
self.setState(self.props.store.getState());
});
},
render : function() {
//make use of this.state...
}
);
var myAppContainerComponent = React.createElement(
myElementClass,
{store : dataStore}
);
ReactDOM.render(myAppContainerComponent, someDOMContainer);
The first forces the app-wide re-render from 'outside', i.e. using ReactDOM. The second does the same thing within the container app.
I've done some performance tests and don't actually see a difference. Will I run in to issues down the road? Is hitting ReactDOM.render() many times an issue?
I know some people will comment that both ways are possibly expensive as they're each re-rendering the whole app (isn't that what React is for ;) ), but that's out of scope of this question.
There is no big difference when you have a few components, but when your app grows large, re-rendering from the top is going to introduce a slowdown. This is why I would recommend subscribing individual components to the store and only using setState() if the part of the state that they care about has changed. This way your components will be much more performant as the app grows.
Finally, we don’t recommend you to use store.subscribe() directly. There is a whole library called React Redux which does the subscription for you! When you use connect() from it, it wraps your components with that setState() logic so you don’t have to write it, and you only need to specify the parts of the state that your components care about. Also, React Redux is more efficient than the code you would write by hand because it contains many optimizations.
I think your components should be a pure function of whatever state happens to be outside of it, but not aware of that state (well, as "pure" as it can reasonably be).
I see a "leaky implementation" here in the second example, meaning that when you have:
componentDidMount : function() {
var self = this;
this.props.store.onChange(function(){
self.setState(self.props.store.getState());
});
},
you are conflating the component itself with the function that is supposed to cause re-rendering of the component.
Your first implementation seems a lot more appropriate to me. Additionally, the first implementation is a lot more re-usable.
In your second example, what if you want to change the structure of your data store, rendering, etc.? Then you may very well have to go into every single component and change it as well.
Bottom line, I definitely like the first implementation better.

Stable reactid for server-side rendering

When using React to render components on the server, I notice that the data-reactid attributes are effectively random. I understand that's expected. (https://groups.google.com/forum/#!topic/reactjs/ewTN-WOP1w8)
However it's a little surprising that this otherwise functional framework introduces such non-determinism in the view output. It means that successive renderings of a view with identical state will create different HTML, preventing, for instance, the view engine from returning a '304 Not Modified' or generating a reliable ETag. (I appreciate such caching could be handled at a higher infrastructure layer as well.)
Is there a way to seed the generation of the identifier so that the reactids are deterministic? Or is the reason that's a bad idea explained somewhere else?
In the final comment on the Google Group thread Ben Alpert says:
For server rendering, it's important that different rendered components don't have colliding IDs (even if they're rendered on different servers, for instance) so we pick them at random.
Also recently thought about it(just started to use reactjs),
Possible solution is quite simple - there is no requirement for ETag to be generated from real html... - it can be generated from displayed data.
So you can generate it from virtual dom - just use React.renderComponentToStaticMarkup(…) and generate ETag from it...
Or you can remove all reactid's from rendered html with regexp before hashing it(likely faster then separate render)...
In case if you are using express, this would be something like:
var virtualDom = React.createFactory(Handler)({});
var html = React.renderToString(virtualDom);
var etag = app.get('etag fn');
if (etag) {
etag = etag(React.renderComponentToStaticMarkup(virtualDom), 'utf8');
etag && res.set('ETag', etag);
}
res.render( ... );
This was bugging me too, so I did some digging to see what would happen if I made the root reactid deterministic.
It is possible override this in React 0.14.x if you're willing to put up with the following hack. In your server-side file where you call ReactDOM.renderToString, place this at the top:
// Override the ServerReactRootIndex.createReactRootIndex function
var ServerReactRootIndex = require('react/lib/ServerReactRootIndex');
ServerReactRootIndex.createReactRootIndex = function(){
return "x"; // Results in an attribute like data-reactid=".x"
};
// Use React as usual
// NB: require('react') must come AFTER overriding ServerReactRootIndex.createReactRootIndex
var React = require('react');
This isn't part of the React API, so this may break in the near future. However, this works for now if you absolutely need it. It also makes the data-react-checksum attribute stable for the same rendered DOM.
If you have multiple root React components in the one page, they MUST have different root ids, so you will need to modify this function to account for this.

Child-to-parent data flow

I'm new to React and still learning the basics. Looking at the tutorial here:
http://facebook.github.io/react/docs/tutorial.html#callbacks-as-props
It's explaining how to make a parent respond to events on a child. Here's the relevant bit of code:
var CommentBox = React.createClass({
handleCommentSubmit: function(comment) {
// TODO: submit to the server and refresh the list
},
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm
onCommentSubmit={this.handleCommentSubmit}
/>
</div>
);
}
}
And then in the CommentForm component:
var CommentForm = React.createClass({
handleSubmit: function() {
var author = this.refs.author.getDOMNode().value.trim();
var text = this.refs.text.getDOMNode().value.trim();
this.props.onCommentSubmit({author: author, text: text});
this.refs.author.getDOMNode().value = '';
this.refs.text.getDOMNode().value = '';
return false;
},
}
If I'm understanding this correctly, instantiating a <CommentForm/> (without any attributes) would create a broken reference when CommentForm.handleSubmit() tries to call this.props.onCommentSubmit(). The parent must rather do <CommentForm onCommentSubmit={some.function}/>. Is this the official way to do child-to-parent data flow in React? Or is there a more loosely-coupled way? I guess I was hoping for something more akin to Backbone's trigger() and on() functions where one view can change which events it listens to without necessarily creating runtime errors in other views.
This is probably the most common form of passing data between components in React. While it's more tightly-coupled than an event-based solution, it's also more explicit (due to less indirection), and React focuses a lot on removing bugs centered around problems with data flow (which can be a problem in large Backbone applications).
Reusable components will often provide an API via their properties. For example, in the CommentForm, it will call the function passed to onCommentSubmit. Components can make this API more explicit by using the propTypes hash. Required properties can be declared with .isRequired, while optional properties leave it off. Components that should function without certain properties should check for the existence of those properties in their handlers, e.g.:
var CommentForm = React.createClass({
handleSubmit: function() {
if (this.props.onCommentSubmit) {
// ...
this.props.onCommentSubmit(...);
}
},
}
Just as passing callbacks around is the most common form of dealing with asynchronous data in Node.js applications, passing functions as properties is the lowest-common-denominator to parent-child component communication in React, and is the best way to ensure any components you build will work with other folks' code. But, just as Node has EventEmitters, promises, fibers, and more, there are plenty of methods you can use to effectively communicate data flow in your React applications. One popular architecture is Flux which offers some more flexibility on the application level while still keeping a clear, one-way data flow; another is the use of an event bus (e.g. with EventEmitter2). Keep in mind, though, what guarantees you're giving up by moving to a more flexible, loosely coupled architecture.

Resources