1. 程式人生 > 其它 >假如有一個需求,我們要在一個頁面中 ul 標籤裡渲染 **十萬** 個 li 標籤

假如有一個需求,我們要在一個頁面中 ul 標籤裡渲染 **十萬** 個 li 標籤

 1 // 插入十萬條資料
 2 const total = 100000;
 3 let ul = document.querySelector('ul'); // 拿到 ul
 4 
 5 // 懶載入的思路 -- 分段渲染
 6 // 1. 一次渲染一屏的量
 7 const once = 20;
 8 // 2. 全部渲染完需要多少次,迴圈的時候要用
 9 const loopCount = total / once;
10 // 3. 已經渲染了多少次
11 let countHasRender = 0;
12 
13 function add() {
14   // 建立虛擬節點,(使用 createDocumentFragment 不會觸發渲染)
15 const fragment = document.createDocumentFragment(); 16 // 迴圈 20 次 17 for (let i = 0; i < once; i++) { 18 const li = document.createElement('li'); 19 li.innerText = Math.floor(Math.random() * total); 20 fragment.appendChild(li); 21 } 22 // 最後把虛擬節點 append 到 ul 上 23 ul.appendChild(fragment);
24 // 4. 已渲染的次數 + 1 25 countHasRender += 1; 26 loop(); 27 } 28 29 // 最重要的部分來了 30 function loop() { 31 // 5. 如果還沒渲染完,那麼就使用 requestAnimationFrame 來繼續渲染 32 if (countHasRender < loopCount) { 33 // requestAnimationFrame 叫做逐幀渲染 34 // 類似於 setTimeout(add, 16); 35 // 幀:一秒鐘播放多少張圖片,一秒鐘播放的圖片越多,動畫就約流暢
36 // 1000/60 = 16 37 window.requestAnimationFrame(add); 38 } 39 } 40 loop();

結論:

  1. 可以使用 document.createDocumentFragment 建立虛擬節點,從而避免引起沒有必要的渲染

  2. 當所有的 li 都建立完畢後,一次性把虛擬節點裡的 li 標籤全部渲染出來

  3. 可以採取分段渲染的方式,比如一次只渲染一屏的資料

  4. 最後使用 window.requestAnimationFrame 來逐幀渲染

思路:

  1. 導致瀏覽器卡頓的原因一般都是操作 DOM 的次數太頻繁。
  2. 如果想要渲染很多條資料不造成卡頓,那麼就一定要儘可能的減少操作 DOM 的次數。
  3. 比方說 React 的虛擬 DOM,本質上就是用 JS 資料來模擬真實 DOM樹,從而大大減少了操作真是 DOM 的次數。
  4. 還有在渲染的時候,可以使用 document.createDocumentFragment 建立虛擬節點,從而避免引起沒有必要的渲染
  5. 也可以採取分段渲染的方式,最後使用 window.requestAnimationFrame 來逐幀渲染