In the react docs, I read:
This pattern is designed to encourage the creation of these simple
components that should comprise large portions of your apps. In the
future, we’ll also be able to make performance optimizations specific
to these components by avoiding unnecessary checks and memory
allocations.
There are several discussions on github like this but these are quite old, what I want to ask is if there are any optimisations done in React v16.0 or before for functional components like implicit shouldComponentUpdate etc. and if these optimisations are done then what are those?
So there isn't any official documentation for FSC (functional stateless components) performance gains over class components. But, I came across this well written medium article that explains how you can get performance gains using FSC.
TLDR: Directly calling functional components as functions instead of mounting them using React.createElement is much faster.
For instance, a FSC looks like this:
const Avatar = (props) => {
return <img src={props.url} />;
}
The way we usually use these components is with the JSX component syntax:
<Avatar url="/path" />
But, through some careful benchmarking and exploration, the author was able to get ~45% speed improvement by calling the FSC as a function:
Instead of mounting them as components, let’s just call them as what they really are: plain JavaScript functions.
Avatar({ url: "/path" });
I think getting performance gains from this method really depends on your app structure, but I thought that it was a neat trick that could potentially be really useful.
There aren't any Optimizations done on the stateless components yet as of v16.0.0 is concerned. The changes that are done from v15 yo v16 are
fragments, error boundaries, portals, support for custom DOM attributes, improved server-side rendering, and reduced file size.
You can see the React Blog for more details on this changes
The only current optimization that I am aware of is that instance objects of stateless components are never created nor retained. So one less object gets created and stored in memory per rendered instance.
Related
After reading a lot of documentations over the web and in SO (here) , most people suggested to use stateless functions (functional components) whenever possible.
Even most life cycle methods of Class components have been replaced by hooks like useState and useEffect.
I've created some projects using hooks and their class equivalents , I see the difference in the amount of code lines and functionality.
So , which one is better over the other ? Functional component of Class component ?
If you mean better -- by means of efficiency, it's very hard to measure. Here is a great post by Dan Abramov on a benchmark where in the end, he says:
Are Hooks always faster than HOCs? No! There are cases where one
approach wins over the other, and it depends on many things.
Now, here is my personal experience:
Our React+Redux SPA was started before the era of hooks, and we have over 100 million users and about 300,000 to 400,000 lines of code (not bragging here, just to have an idea that it is indeed a large application).
When hooks were officially released for Production and we finally updated our React version, modals, inputs, buttons, image loaders, and many other simple components looked amazing when migrated from class components to functional ones with hooks.
The code became much cleaner and easier to maintain. Some Components/HOCs went from 50-100 lines to just 20 or 30 using hooks. That's amazing!
However, complex pages and container components on the other hand, looked a lot messier. Our Routes, for example, I feel look better using class components.
In these cases, readability using class components is far superior.
Regarding performance, again, I don't think there is a big difference and we almost never had to worry about it, so long the code is well-written.
I created a small project (Markdown Tables Generator) as a sandbox and practice using only functional components and hooks. I really like the useSelector() and useDispatch() hooks, but when asked by a company once on an interview if I would go all-in hooks on their medium/large-sized project, I said I wouldn't.
Hope my experience helps you and I suggest you try both, considering the scope of your project. The great thing about React is that both of them can be mixed up almost seamlessly.
Once component implements componentDidCaught it has to be class based component.
Throttling/debouncing/interval-based logic also looks much better(more clear, more readable) in class with access by reference than in functional component with its closures and useEffect.
Otherwise functional looks better(code is shorter - especially when we use Context API or hooks instead HOC like happens for Redux, better DRY thanks to custom hooks, better control over side effects thanks to useEffect - when to run, how to cancel).
ps and with hooks they are not stateless anymore. Just "functional".
I am not an expert in react so I am a little confused but since the introduction of react hooks. when do you use class components instead of functional components?
I would use class when there is something that functional components can't implement like state or lifecycle methods, waitttttttttttttttttt...
Since hooks have the state and lifecycle methods you don't need classes anymore :)
Your typical lifecycle methods have been replaced with useEffect, which reduces the amount of code you have significantly. You don't need to define multiple methods (componentDidMount, componentDidUpdate, etc) when you can use a single hook to take care of them all.
The other advantage is that they can start with much less boilerplate code than their class equivalent, and scales much better considering you don't need to replace multiple methods when reworking features in such a component.
The main reason you can still use classes is because there's no reason to remove them - they're still a core part of what React is and how it works. Hooks are newer and follow a completely different design approach to what everyone already knows. They're completely compatible with one another.
I have a react/redux application which has become large enough to need some performance optimizations.
There are approx ~100 unique components which are updated via websocket events. When many events occur (say ~5/second) the browser starts to slow down significantly.
Most of the state is kept in a redux store as Immutable.js objects. The entire store is converted to a plain JS object and passed down as props through the component tree.
The problem is when one field updates, the entire tree updates and I believe this is where there is most room for improvement.
My question:
If the entire store is passed through all components, is there an intelligent way to prevent components updating, or do I need a custom shouldComponentUpdate method for each component, based on which props it (and its children) actually use?
You really don't want to do things that way. First, as I understand it, Immutable's toJS() is fairly expensive. If you're doing that for the entire state every time, that's not going to help.
Second, calling toJS() right away wastes almost the entire benefit of using Immutable.js types in the first place. You really would want to keep your data in Immutable-wrapped form down until your render functions, so that you get the benefit of the fast reference checks in shouldComponentUpdate.
Third, doing things entirely top-down generally causes a lot of unnecessary re-rendering. You can get around that if you stick shouldComponentUpdate on just about everything in your component tree, but that seems excessive.
The recommended pattern for Redux is to use connect() on multiple components, at various levels in your component tree, as appropriate. That will simplify the amount of work being done, on several levels.
You might want to read through some of the articles I've gathered on React and Redux Performance. In particular, the recent slideshow on "High Performance Redux" is excellent.
update:
I had a good debate with another Redux user a couple days before this question was asked, over in Reactiflux's #redux channel, on top-down vs multiple connections. I've copied that discussion and pasted it in a gist: top-down single connect vs multiple lower connects.
Also, yesterday there was an article posted that conveniently covers exactly this topic of overuse of Immutable.js's toJS() function: https://medium.com/#AlexFaunt/immutablejs-worth-the-price-66391b8742d4. Very well-written article.
I'm new to React (and React Native in particular), and I'm trying to come up with the right application design.
I have a separate JavaScript module, unrelated to React; the module contains some objects with methods, some of them mutate objects, some have side effects (like, subscribe/unsubscribe to/from the server events, or add/remove listeners to local object's events), etc.
I'd like to reuse this JavaScript module inside my React Native app, but it seems that it won't play well together. In Redux (and some other state managers as well), state needs to be represented as a plain immutable JS object, and instead of mutating existing objects, we create new objects instead. So I can't use my existing JS objects as a state directly.
I probably could use some wrappers around my existing JS code (mutating, and full of side effects), but it doesn't seem a nice solution: a lot of repetition, and the end result is unlikely to be elegant.
On the other hand, I'm not quite happy reimplementing the whole thing to fit into React's world, to make it idiomatic.
And on the one more other hand, I could just forget about Redux, and use plain state of React's components, but I feel it'll be a mess.
I'd like to get some suggestions from experiensed React + Redux people. What would you recommend?
It's hard to say exactly without seeing what the mystery module does or exposes. But consider converting the module into one or more reducers and then use Redux's combineReducers to target pieces of the overall store that will be contained exclusively in your module.
Then you will need to add reducer methods that always return new objects as required by Redux, but you won't need to modify every function in the existing code.
This article by Dan Abramov helped me understand reducer composition.
See also Handling Actions in the docs for help on how to write good reducer methods that only modify a small piece of the store.
I'm trying to get to grips with highly-decoupled, low-cohesion patterns for designing components.
I'm designing each Feature of a larger system as a Web Component - analogous to the concept of a "Module" in design patterns, e.g Export-PDF functionality, Boards functionality etc.
The issue is that some components are dependent between them - they call methods of each, have access to their public variables etc.
Since each component needs to be testable in isolation, must be highly-decoupled, must have low inter-dependency with other components, what are some classroom examples for decoupling one from one another?
Considering this scenario:
User presses CTRL+P
Keybindings are handled by the Shortcuts Component
Shortcuts Component calls Export-PDF Component .print() method.
Some solutions I've though about:
Use events
Each component dispatches an event which is then caught in the other component, e.g using this.addEventListener(...
Pros:
Allows testing in isolation since there are no direct calls to another component's methods.
Cons:
Will result in many dispatches/listeners which might impact performance.
There is still a lot of coupling and it has the potential of getting unmanageable.
Use direct calls to methods of the other component
Each component simply calls the other components method directly, e.g exportPDF.printPages().
Pros:
It's the most simple.
Cons:
Each component is interdependent to one another.
Component is NOT testable in isolation.
What are some other methods of decoupling components?
For the record, the language of interest is JavaScript.
Although concepts and methods might be applicable across many programming languages, I'm specifically talking about concepts and solutions to the problems using features that JavaScript has.