解決方案:能夠從減小 DOM 操做次數、縮短循環時間兩個方面減小主線程阻塞的時間app
<li>
分批次插入到頁面中,每次插入的時機是在頁面從新渲染以前,採用 requestAnimationFrame
。代碼示例:spa
(() => { const ndContainer = document.getElementById('js-list'); if (!ndContainer) { return; } const total = 30000; const batchSize = 4; // 每批插入的節點次數,越大越卡 const batchCount = total / batchSize; // 須要批量處理多少次 let batchDone = 0; // 已經完成的批處理個數 function appendItems() { const fragment = document.createDocumentFragment(); for (let i = 0; i < batchSize; i++) { const ndItem = document.createElement('li'); ndItem.innerText = (batchDone * batchSize) + i + 1; fragment.appendChild(ndItem); } // 每次批處理只修改 1 次 DOM ndContainer.appendChild(fragment); batchDone += 1; doBatchAppend(); } function doBatchAppend() { if (batchDone < batchCount) { window.requestAnimationFrame(appendItems); } } // 執行 doBatchAppend(); ndContainer.addEventListener('click', function (e) { const target = e.target; if (target.tagName === 'LI') { alert(target.innerHTML); } }); })();