分片渲染一万条数据

根据数据大小划分,每次加载固定的条数,例如

  1. 一万条数据,每次渲染 100条;
  2. 然后再渲染 100条,递归实现分片渲染;
  3. 缺点
    1. 页面DOM会100条,100条的递增,页面会有抖动
    • DOM渲染太多,一万条数据,页面滚动卡顿

递归实现分片渲染

  1. const container = document.querySelector('#root')
  2. const total = 10000;
  3. const bufferSize = 100; // 每次渲染 100条
  4. let index = 0;
  5. let id = 0;
  6. let timer = Date.now();
  7. loadDom()
  8. function loadDom() {
  9. index += bufferSize;
  10. if(index > total) return;
  11. // 分片渲染,定时器是一个宏任务,会等待 GUI线程渲染完成后再执行
  12. setTimeout(() => {
  13. for(let i = 0; i< bufferSize; i++) {
  14. const el = document.createElement('p');
  15. el.innerHTML = ++id;
  16. container.appendChild(el);
  17. }
  18. // 10000条数据的执行时间
  19. console.log('JS-render100',Date.now() - timer)
  20. loadDom() // 递归
  21. }, 0)
  22. }
  23. // 同步代码先执行
  24. console.log('JS-render',Date.now() - timer)
  25. // 渲染DOM时间
  26. setTimeout(() => {
  27. console.log('DOM-render',Date.now() - timer)
  28. }, 0)

image.png

分片渲染优化

  1. requestAnimationFrame代替 setTimeout
  2. document.createDocumentFragment 代替 document.createElement ```jsx const container = document.querySelector(‘#root’) const total = 10000; const bufferSize = 100; let index = 0; let id = 0; let timer = Date.now();

loadDom() function loadDom() { index += bufferSize; if(index > total) return;

const fragment = document.createDocumentFragment(); requestAnimationFrame(() => { for(let i = 0; i< bufferSize; i++) { const el = document.createElement(‘p’); el.innerHTML = ++id; fragment.appendChild(el); } container.appendChild(fragment); // 100条数据的执行时间 console.log(‘JS-render100’,Date.now() - timer) loadDom() // 递归 }) }

// 渲染DOM时间 setTimeout(() => { console.log(‘DOM-render’,Date.now() - timer) }, 0)

  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/112859/1651383248244-d025c7de-f7c3-4967-9171-4c03b002bc6d.png#clientId=u7467fd27-7eb3-4&from=paste&height=225&id=u9e8527a5&originHeight=494&originWidth=602&originalType=binary&ratio=1&rotation=0&showTitle=false&size=52409&status=done&style=none&taskId=u3d8c89be-790e-4bc3-b7ff-fbbe23da72d&title=&width=273.6363577054553)
  2. <a name="sfs8N"></a>
  3. ## 一次性渲染一万条数据
  4. 页面渲染1万条 DOM
  5. - JS渲染生成一万条数据,耗时 95ms
  6. - DOM渲染到页面,耗时 可以646ms
  7. - 缺点
  8. - 页面 loading时间长,白屏时间长
  9. - DOM渲染太多,一万条数据,页面滚动卡顿
  10. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/112859/1651381186847-49124788-c771-43c8-84bd-ed22dae45afe.png#clientId=u7467fd27-7eb3-4&from=paste&height=62&id=u3610e451&originHeight=136&originWidth=434&originalType=binary&ratio=1&rotation=0&showTitle=false&size=11685&status=done&style=none&taskId=u4659ba19-ec0c-478e-bf4d-416e3b9c5f6&title=&width=197.27272299695616)
  11. ```jsx
  12. const container = document.querySelector('#root')
  13. const total = 10000;
  14. const timer = Date.now();
  15. for(let i = 0; i< total; i++) {
  16. const el = document.createElement('p');
  17. el.innerHTML = i;
  18. container.appendChild(el);
  19. }
  20. // 10000条数据的执行时间
  21. console.log('JS-render', Date.now() - timer)
  22. // 渲染DOM时间
  23. setTimeout(() => {
  24. console.log('DOM-render', Date.now() - timer)
  25. }, 0)