I have a component that wraps a bunch of ReactList components.
ReactList component is a component that does infinite scrolling ie only load what's on viewport. It has couple of modes: simple and uniform. I'm using simple which just loads and loads as you scroll down (making the scrollable page longer). Uniform loads and removes the above section that is now out of viewport. I tried using uniform mode, and if it worked I wouldn't even need to ask what I'm about to, but it's super buggy and defeats the purpose. Simple on the other hand is super fast scrolling and loading is equally fast.
I broken down my list into few groups where user can click and it will load that ReactList component. If the scrollable page is short, ie, user hasn't scrolled all the way down, changing between the group of lists is fast enough. ~2s. However, if the page is scrolled all the way down, and trying to change list takes ~6s.
I noticed that the page is fully loaded too, ie nothing more to load. So okay, I think maybe if I change the key for the wrapper parent component and just remount the component, it should be fast right? Nope. The component that reloads is short, only one viewport length, but it takes around ~5s.
I noticed changing out of the fully loaded list component page to just regular single line text "Hello world" component still took around the same amount! ~5s. What's up with that?
QUESTION: Why is unmounting a long page with many small components in a list take so long to just unmount?
Sorry I realize this is long and full of text but I thought I should explain my situation.
As it is an old question, I really want to put it to an end.
Quick answer: use virtual list, something like uniform mode you described, but better maintained with better api. You can get bunch of packages if you search react virtual list, use ones with more stars and better maintained, and most of all fit your case.
Surely you got lots of small components when you scroll. In react it's not like removing a node is one shot thing, it needs to unmount every leaf from the tree, and recursively unmount leaves untuil reach that node. So if you got a lot of components, even today's new react won't help you out.
With virtual list, you get less components although your user doesn't know, so it would be quick.
Related
Say you are passing a prop called show to a component. If the prop value is true, you should render the full component normally. If it is false, you should not display anything.
You can do this two ways.
return null in the render method of the component.
apply a CSS class containing display: none attribute to the component's DOM element.
Which ones is the correct or the preferred way?
I do not think there will be any definite answer for this question.
Each approach has its benefits and drawbacks.
With CSS you have:
it might work faster
no need to think about restoring child control states if control is shown again.
With returning null:
the total rendered DOM might be considerably smaller. This is important if you have many such components that might be hidden.
there will be no collisions in rendered html. Lets say you have tabular view. Each tab is its own complex form with many child controls. If you have some raw javascript/jquery/whatever working with their ids/classnames etc. - its quite hard to ensure each tab/form has unique ids, unless you do not render them.
From my point of view the decision will be based upon the structure of your control. If it have complex structure with many nested children and you do not have any means of restoring their states when switched on again - go with CSS, but I would say this is a short term solution for quite simple controls only. In all other cases I would go with not rendering a component.
If you think you would need to display the component again, during that page life, then I would recommend using css way, as the impact on DOM manipulation would be less in that case. In some other cases probably returning null would be more helpful.
For the most part, your two solutions are interchangeable. They both "work" fine.
I would warn against preemptive optimization in choosing which of these methods to choose. If you do need to eventually modify your code and try the other method, this is an absurdly simple swap to make and shouldn't be an obstacle. So don't worry about it until there's a reason to worry about it.
I'm the OP.
If components are hidden depending on the screen size, CSS media queries and display: none works the best if the app is pre-rendered using something like react-snap. This is because, if the pre-rendered device and the viewing device don't match, the layout would change when the app rehydrates if the component hiding logic is in JS.
Related to that, we need to be careful that even though the component is not "shown" with CSS display: none, the component is still there and if there are effects, they will still fire.
I've created a SPA Hearthstone card search that shows all (currently ~1200) cards on the same page. Site. The problem I have is that due to all 1200 cards being displayed on the same page it takes really long time to render. How would I best tackle this problem?
My ideas so far:
Lazy render parts of array that aren't immediately visible. This would seem best, but I don't know if it's possible and how. There's a package for react that seems to do this, so I guess it's possible somehow? I guess I could make a separate array for shown cards, which I would lazy append from first array based on how much the user has scrolled
Pagination. Obvious one, but it makes for some counter-intuitive behaviour along with the filters I have. I would like to avoid using pagination if possible.
For reference - here's the code for rendering the cards.
How would I go about making this render faster? Is lazy rendering possible and how is it best done?
So I have an app that has a right sidebar whose visibility is toggled via a button. In that sidebar there can be one of several things [at a time] - chat, help, search. I was looking at some plain HTML from apps which have a similar feature and noticed that they have all nodes rendered, but are just hidden via CSS.
Since I need to do the same thing, I was thinking whether this would be a good idea to do with React. But then I realized that React elements have a state which when updated calls the render method. So I can use the state to store both whether the sidebar is opened, and what is inside the sidebar.
Is that the React way of doing things? Is it better to have all nodes rendered even if they are not visible, or is it better to have the nodes rendered on request via state changes?
My feeling is that only rendering what is visible would be the more standard React way, but in this case, this is mainly a performance decision. If you render everything and just toggle visibility with CSS, the first render will take longer (but the time difference may not be relevant or even noticeable). If you render only the part that's visible, React needs to do a small rerender every time the sidebar content changes. (This may also not be noticeable time.)
My recommendation would be to try both, if you want to test the performance. But I think you won't go too wrong either way.
I have an UI built in Flux/React that mimics an OS windows system. User can move, minimize, and resize windows but also drag'n'drop icons between windows. I have main Desktop component which polls LayoutStore and builds children based on layout data.
It turns out however that rerendering the virtual DOM tree with more elements takes long enough to impair app responsiveness sometimes which is bad for transition animations. I already gave up on updating state at 60fps - I just update layout store after user drops an element. I was thinking about ways to limit render calls since I know that most changes to the layout affect child components very selectively - there is low chance that a given layout state change affects more than one particular component.
What I came up with is keeping a dirty or stateVersion variable in LayoutStore for each larger component (i.e. a window) and passing it in props so that each component could check if it was affected very fast without worrying about complexity of state representation (no deep comparisons, immutable copies, etc.) Also I prefer the second way cause I can just bump component's stateVersion each time I mess with its properties and don't need to unset dirty back in the store after emitting change.
Since I'm very new to React - is it a sane approach given my constraints or is there a better standard solution?
I have a question about div caching in ember js for views.
I am rendering a really heavy flash application as a part of a view and i want to switch between views but not necessarily have to reload the flash app from scratch. I would preferably want it to be "hidden".
Is there a way of doing this in ember
Currently i am implementing this using https://github.com/ghempton/ember-routemanager and one of the flash apps stay on /#media and the other on /#publishing
So when user goes to /#media the media.swf gets loaded and /#publishing the publishing.swf gets loaded into the container div. Each of these routes have a corresponding view class associated to them that renders the flash object tag to be rendered.
In the past, I have used jquery to hide the container div but i am searching for a cleaner solution.
It sounds like the feature you'd like is to be able to reuse a view instance and it's DOM across states. I have some ideas for how that could be done, unfortunately it's not possible right now without some nasty hacks.
Also, unfortunately with flash objects, they seem to get rerendered if you move them in the DOM or if you change their visibility. From what I can tell, to "hide" a flash object without causing a rerender, you can only move it off screen using CSS.
Update:
Here's a working jsFiddle example: http://jsfiddle.net/EE3B8/1
Unfortunately, that technique won't work for Flash objects, since moving them in the DOM will cause them to be reloaded. This would be a good way of eliminating expensive DOM creation/view instantiation.