頁面海量資料優化載入
阿新 • • 發佈:2018-12-10
要求:將10W條資料一次渲染到頁面上?
分析: ·資料量過大,出現卡頓感的主要原因是,在每次迴圈中,都會修改 DOM 結構,並且由於資料量大,導致迴圈執行時間過長,瀏覽器的渲染幀率過低。 ·從 減少 DOM 操作次數 和 縮短迴圈時間 兩個方面減少主執行緒阻塞的時間. ·通過 DocumentFragment 的使用,減少 DOM 操作次數,降低迴流對效能的影響; ·在縮短迴圈時間方面,我們可以通過 分治 的思想,將 100000 個 li 分批插入到頁面中,並且我們通過 requestAniminationFrame 在頁面重繪前插入新節點。 DocumentFragment節點不屬於文件樹,繼承的parentNode屬性總是null。它有一個很實用的特點,當請求把一個DocumentFragment節點插入文件樹時,插入的不是DocumentFragment自身,而是它的所有子孫節點。這個特性使得DocumentFragment成了佔位符,暫時存放那些一次插入文件的節點。
HTML:
<ul id="oUl"></ul>
JS:
(function () { const oUl = document.getElementById("oUl"); //防禦性程式設計 if(!oUl){ return; } const total = 10000; //插入資料的總數 const size = 4; //每次批量插入的節點數,個數越多,頁面越卡頓 const count = total/size; //批處理的次數 let num = 0; //完成處理的次數 //往列表插入 10w 個 li ,每個列表項的文字內容可自行定義 function appendItems() { //使用 DocumentFragment 減少 DOM 操作次數,對已有元素不進行迴流 const fragment = document.createDocumentFragment('li'); for(let i=0;i<size;i++){ const li = document.createElement("li"); li.innerText = num * size + i + 1; fragment.appendChild(li); } //每次批處理只修改一次DOM oUl.appendChild(fragment); num++; doAppendBatch(); } function doAppendBatch(){ if(num < count){ window.requestAnimationFrame(appendItems); // 在重繪之前,分批插入新節點 } } doAppendBatch(); //要求當每個 li 被單擊時,通過 alert 顯示列表項內的文字內容 //使用 事件委託 ,利用 JavaScript 的事件機制,實現對海量元素的監聽,有效減少事件註冊的數量 oUl.addEventListener("click",function (e) { var e = e || window.event; //相容IE const target = e.target || e.srcElement; if(target.nodeName.toUpperCase() === "LI") alert(target.innerText); }) })();