vendrick
vendrick

Reputation: 538

How to render thousands of div without affecting app performance?

I'm trying to make something like Reddit r/place. The problem is:

When there are like 10k square div already on screen, if I press a button (assume async fetch or displaying a pop-up) it gets executed after a huge delay like up to 4-5 seconds. I've checked stuff and it looks like nothing re-renders but still, I think having that amount of div in DOM causes incredible lag.

Unfortunately, this cannot be solved with react-virtualized or react-window because I want to display all of the squares at once. So, hiding undisplayed elements won't solve this since I want to display them all.

The question is: What is the proper way to have ten thousand 10x10px div without causing huge lag on React app?

Upvotes: 0

Views: 1192

Answers (1)

Som Shekhar Mukherjee
Som Shekhar Mukherjee

Reputation: 8168

Adding the following example for reference till you're updating your question.

I've rendered 10K divs and since the divs are static (meaning they don't re-render), I can fetch data and re-render other components without any problem.

So, if the divs are static, the initial load might be slow but after the divs are painted if you don't re-render them it shouldn't be a problem.

function AsyncData() {
  const [data, setData] = React.useState(null);

  function fetchData() {
    setData(null);
    fetch("https://jsonplaceholder.typicode.com/todos/1")
      .then((res) => res.json())
      .then(setData);
  }

  return (
    <div>
      <button onClick={fetchData}>Fetch Data</button>
      {data && <pre>{JSON.stringify(data, null, 2)}</pre>}
    </div>
  );
}

function Square() {
  return <div className="square"></div>;
}

function App() {
  return (
    <div className="app">
      <div className="square-container">
        {Array.from({ length: 10000 }, (_, i) => (
          <Square key={i} />
        ))}
      </div>
      <AsyncData />
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById("root"))
.square {
  width: 0.625em;
  height: 0.625em;
  background: #eee;
  margin: 0.125em;
}

.square-container {
  padding: 1em;
  max-height: 3em;
  display: flex;
  flex-wrap: wrap;
  overflow-y: auto;
  background: #ccc;
  margin-bottom: 1em;
}
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>

Upvotes: 1

Related Questions