• 页面加载海量数据优化方案


    题目:10w 条记录的数组,一次性渲染到页面上,如何处理可以不冻结UI?

    页面上有个空的无序列表节点 ul ,其 id 为 list-with-big-data ,现需要往列表插入 10w 个 li ,每个列表项的文本内容可自行定义,且要求当每个 li 被单击时,通过 alert 显示列表项内的文本内容。

    <!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>页面加载海量数据</title>
    </head>
    
    <body>
      <ul id="list-with-big-data">100000 数据</ul>
      <script>
        // 此处添加你的代码逻辑
      </script>
    </body>
    </html>

    分析:我们可以从 减少 DOM 操作次数 和 缩短循环时间 两个方面减少主线程阻塞的时间。

      可以通过 DocumentFragment 的使用,减少 DOM 操作次数,降低回流对性能的影响。

      在缩短循环时间方面,我们可以通过 分治 的思想,将 100000 个 li 分批插入到页面中,并且我们通过 requestAniminationFrame 在页面重绘前插入新节点。

    (function() {
      const ulContainer = document.getElementById("list-with-big-data");
    
      // 防御性编程
      if (!ulContainer) {
        return;
      }
    
      const total = 100000; // 插入数据的总数
      const batchSize = 4; // 每次批量插入的节点个数,个数越多,界面越卡顿
      const batchCount = total / batchSize; // 批处理的次数
      let batchDone = 0; // 已完成的批处理个数
    
      function appendItems() {
        // 使用 DocumentFragment 减少 DOM 操作次数,对已有元素不进行回流
        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);
        }
    
        // 每次批处理只修改 1 次 DOM
        ulContainer.appendChild(fragment);
        batchDone++;
        doAppendBatch();
      }
    
      function doAppendBatch() {
        if (batchDone < batchCount) {
          // 在重绘之前,分批插入新节点
          window.requestAnimationFrame(appendItems);
        }
      }
    
      // kickoff
      doAppendBatch();
    
      // 使用 事件委托 ,利用 JavaScript 的事件机制,实现对海量元素的监听,有效减少事件注册的数量
      ulContainer.addEventListener("click", function(e) {
        const target = e.target;
    
        if (target.tagName === "LI") {
          alert(target.innerText);
        }
      });
    })();
    
  • 相关阅读:
    Android—应用程序开机自启
    Android—简单的仿QQ聊天界面
    Android—关于自定义对话框的工具类
    Android—基于GifView显示gif动态图片
    Android—ListView条目背景为图片时,条目间距问题解决
    Android—自定义开关按钮实现
    FileProvider的使用
    Android 7.0新特性
    Android SDK自带调试优化工具
    Android监视器概述
  • 原文地址:https://www.cnblogs.com/guoxianglei/p/8979066.html
Copyright © 2020-2023  润新知