Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React non-blocking rendering of big chunks of data

Recently I started to learn to react and wondering, is there some kind of pattern for non-blocking UI thread rendering for big data. Let's say, we take this example: , click create a lot of items, set number for, let's say 10000, we will get frozen UI for almost 10 seconds. It updates smoothly with observables, once it is done rendering, I get that, but is there a way to render it smoothly, in chunks?

Usually, you set up some kind of array, slice it by, let's say 50, process those and setTimeout for 0 to slice another 50 and so on. Repeat til array's length is 0. Is there a pattern for react components for doing that? Maybe some plugin or until mixin?

like image 940
user1929437 Avatar asked Feb 04 '16 06:02

user1929437


People also ask

How do you render a large amount of data in react?

Another way to render a large amount of data is with infinite scroll. Infinite scroll involves appending data to the end of the page as you scroll down the list. When the page initially loads, only a subset of data is loaded. As you scroll down the page, more data is appended. There are several ways to implement infinite scroll in React.

What is an element in react rendering?

Rendering Elements. Elements are the smallest building blocks of React apps. An element describes what you want to see on the screen: const element = <h1>Hello, world</h1>; Unlike browser DOM elements, React elements are plain objects, and are cheap to create. React DOM takes care of updating the DOM to match the React elements. Note:

How do I render a react element as a root node?

Applications built with just React usually have a single root DOM node. If you are integrating React into an existing app, you may have as many isolated root DOM nodes as you like. To render a React element into a root DOM node, pass both to ReactDOM.render (): It displays “Hello, world” on the page.

How often does reactdom render in react?

It calls ReactDOM.render () every second from a setInterval () callback. In practice, most React apps only call ReactDOM.render () once. In the next sections we will learn how such code gets encapsulated into stateful components.


4 Answers

You can use requestIdleCallback to defer the render:

function DeferredRender({ children, idleTimeout }) {
  const [render, setRender] = React.useState(false);

  React.useEffect(() => {
    if (render) setRender(false);
    const id = requestIdleCallback(() => setRender(true), { timeout: idleTimeout });

    return () => cancelIdleCallback(id);
  }, [idleTimeout]);

  if (!render) return null;

  return children;
}
<DeferredRender idleTimeout={1000}>
 <ExpensiveStuff />
</DeferredRender>

like image 165
nullspace Avatar answered Sep 24 '22 18:09

nullspace


For a similar problem, I chunked my data and then serialized the processing with reduce and promises:

chunks.reduce( (previousPromise, nextChunk) => {
  return previousPromise.then(processChunkAndUpdateComponentStateAsPromise(nextChunk));
}, Promise.resolve());
like image 38
Markus Avatar answered Sep 23 '22 18:09

Markus


React Concurrent Mode is solving the UI stall problem. You can watch some talks [1] [2] to understand how. This doesn't make your UI magically update faster, it only helps you make the UI not freeze while your UI updates.

Your two options are to either:

  1. update the state in chunks, as you said. If you chunk the work don't just do so based on time: you can't hard-code an optimal value based on time because people's computers perform differently. Instead either use the browser APIs like requestIdleCallback or look into the scheduler NPM library (https://philippspiess.com/scheduling-in-react/) in order to do the work as aggressively as possible but in a scheduled manner that doesn't lead to browser hangs.
  2. or use a library to have a virtualized list, as another person already answered.
like image 27
Alan Avatar answered Sep 21 '22 18:09

Alan


For lists as large as 10,000 items I would recommend using a virtualized list. A popular implementation of this for React is react-virtualized: http://bvaughn.github.io/react-virtualized/#/components/List.

The reason for this is that a virtualized list will only render what is visible, so it will be fast even if you have a lot of data to display. You could also split your initial render into batches, but if you do this you are likely to run into other performance issues (due to too much DOM, too many observables, etc).

like image 41
Joru Avatar answered Sep 20 '22 18:09

Joru