Page Loading Massive Data Optimization Solution

Topic: An array of 10w records is rendered to the page at one time. How can I avoid freezing the UI?

There is an empty unordered list node on the page  ul , which  id is  list-with-big-data , now need to insert 10w into the  li list, the text content of each list item can be defined by yourself, and when each  li is clicked, it is  required to alert display the text in the list item by displaying content.

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>The page loads massive data</title>
</head>

<body>
  <ul id="list-with-big-data">100000 数据</ul>
  <script>
    // Add your code logic here
  </script>
</body>
</html>

Analysis: We can reduce the blocking time of the main thread from two aspects: reducing the number of DOM operations and shortening the cycle time.

  It can be  DocumentFragment used to reduce the number of DOM operations and reduce the impact of reflow on performance.

li In terms of shortening the cycle time, we can insert 100,000 batches into the page    through the divide and conquer idea,  and we do this by requestAniminationFrame inserting new nodes before the page is redrawn.

(function() {
  const ulContainer = document.getElementById("list-with-big-data");

  // defensive programming 
  if (! ulContainer) {
     return ;
  }

  const total = 100000 ; // The total number of inserted data 
  const batchSize = 4 ; // The number of nodes inserted in each batch, the more the number, the more stuck the interface 
  const batchCount = total / batchSize; // The number of batches 
  let batchDone = 0 ; // Number of completed batches

  function appendItems() {
    // Use DocumentFragment to reduce the number of DOM operations, and do not reflow existing elements 
    const fragment = document.createDocumentFragment();

    for (let i = 0; i < batchSize; i++) {
      const liItem = document.createElement("li");
      liItem.innerText = batchDone * batchSize + i + 1 ;
      fragment.appendChild(liItem);
    }

    // Only modify the DOM once per batch 
    ulContainer.appendChild(fragment);
    batchDone++;
    doAppendBatch();
  }

  function doAppendBatch() {
    if (batchDone < batchCount) {
       // Insert new nodes in batches before redrawing 
      window.requestAnimationFrame(appendItems);
    }
  }

  // kickoff
  doAppendBatch();

  // Using event delegation and JavaScript's event mechanism to monitor massive elements and effectively reduce the number of event registrations 
  ulContainer.addEventListener( " click " , function(e) {
     const target = e.target;

    if (target.tagName === "LI") {
      alert(target.innerText);
    }
  });
})();

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325156313&siteId=291194637