JavaScript 操作DOM效能優化
JavaScript主要功能之一就是用來操作DOM,但操作DOM是非常昂貴的行為。
在初學階段,達成目標是主要目標,隨著技術的進步,會自然而然的關注程式碼的效能。
程式碼的效能對於小型的專案影響不是太大,但是對於大型專案或者操作量較高的專案則有明顯的影響。
下面介紹一下常見的提高效能的方式。
一.遍歷元素集合:
應用中,可能需要使用指定方法獲取元素物件集合,然後對其進行遍歷。
程式碼例項如下:
[HTML] 純文字檢視 複製程式碼執行程式碼<!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.softwhy.com/" /> <title>螞蟻部落</title> <style type="text/css"> #box li { width: 350px; height: 25px; line-height: 25px; font-size: 12px; } </style> <script> addEventListener("DOMContentLoaded",function(){ let lis=document.getElementsByTagName("li"); for(let index=0;index<lis.length;index++){ lis[index].style.color="blue"; } },false); </script> </head> <body> <ul id="box"> <li>螞蟻部落一</li> <li>螞蟻部落二</li> <li>螞蟻部落三</li> <li>螞蟻部落四</li> <li>螞蟻部落五</li> <li>螞蟻部落六</li> </ul> </body> </html>
程式碼分析如下:
(1).通過getElementsByTagName方法獲取li元素集合。
(2).此集合是動態的,也就是它能夠自動實時感知li元素的增加或者減少。
(3).然後通過for迴圈遍歷每一個li元素,再將其字型元素設定為藍色。
上述程式碼並不是最優方式,由於集合是動態的,所以lis.length獲取集合中的元素數量效能較差。
那麼可以將元素集合的數量事先快取起來,而不是每迴圈一次獲取一次,程式碼修改如下:
[JavaScript] 純文字檢視 複製程式碼addEventListener("DOMContentLoaded",function(){ let lis=document.getElementsByTagName("li"); let len=lis.length; for(let index=0;index<len;index++){ lis[index].style.color="blue"; } },false);
二.將多次樣式操作合併為一次:
實際應用中,可能會使用如下方式設定元素的樣式,程式碼片段如下:
[JavaScript] 純文字檢視 複製程式碼let odiv = document.getElementById("ant"); odiv.style.color = "red"; odiv.style.background = "blue"; odiv.style.width = "200px"; odiv.style.height = "100px";
上述程式碼可以設定div元素的字型顏色、背景顏色和元素尺寸。
一切看起來很正常,但是效能比較低下,如果操作龐大,效能會有明顯下降。
因為每一次使用style設定,都會引發頁面的重繪或者重排,程式碼修改如下:
CSS程式碼如下:
[CSS] 純文字檢視 複製程式碼#ant { background: blue; color: red; width:200px; height: 200px; }
JavaScript程式碼如下:
[JavaScript] 純文字檢視 複製程式碼let odiv = document.getElementById("ant"); odiv.className = "ant";
使用上述程式碼,重繪和重排只有一次,可以極大提高想能。
重繪和重排是非常消耗效能的行為,具體參閱JavaScript 重繪和重排簡介一章節。
三.經常需要重排的元素設定為絕對定位:
有些元素可能需要經常重排,那麼可以將它們設定為絕對定位。
這樣它們就可以脫離文件流,即便它們發生重排也不會影響其他元素,縮小了重排的範圍。
四.使用fragment暫存節點:
假設我們需要依次建立若干個li元素,然後將其追加到ul中。
ul中追加li元素是一個重繪或者重排操作,很消耗效能,看如下程式碼片段:
[HTML] 純文字檢視 複製程式碼執行程式碼<!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.softwhy.com/" /> <title>螞蟻部落</title> <script> addEventListener("DOMContentLoaded",function(){ let arr=["螞蟻部落一","螞蟻部落二","螞蟻部落三","螞蟻部落四","螞蟻部落五"]; let oul=document.getElementById("box"); for(let index=0;index<5;index++){ let li=document.createElement("li"); let oTxt=document.createTextNode("螞蟻部落"+arr[index]); li.appendChild(oTxt); oul.appendChild(li); } },false); </script> </head> <body> <ul id="box"></ul> </body> </html>
上述程式碼通過for迴圈方式依次建立li元素,然後再依次將li元素追加到ul元素中。
雖然實現了預期效果,但是效能非常不好,因為進行了多次追加操作,進行了多次重繪重排。
所以可以將每一次附加操作暫存起來,然後一次性追加到ul中,進行一次重繪重排操作即可。
程式碼修改如下:
[HTML] 純文字檢視 複製程式碼執行程式碼<!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.softwhy.com/" /> <title>螞蟻部落</title> <script> addEventListener("DOMContentLoaded",function(){ let arr=["螞蟻部落一","螞蟻部落二","螞蟻部落三","螞蟻部落四","螞蟻部落五"]; let oFragment=document.createDocumentFragment(); let oul=document.getElementById("box"); for(let index=0;index<5;index++){ let li=document.createElement("li"); let oTxt=document.createTextNode("螞蟻部落"+arr[index]); li.appendChild(oTxt); oFragment.appendChild(li); } oul.appendChild(oFragment); },false); </script> </head> <body> <ul id="box"></ul> </body> </html>
程式碼實現了相同的效果,但是效能更佳,分析如下:
(1).利用document.createDocumentFragment方法建立一個暫存器。
(2).然後將附加操作放入這個暫存器。
(3).最後將暫存器附加到ul中,事實就是將所有li元素一次性附加到ul。
關於document.createDocumentFragment方法參閱document.createDocumentFragment()一章節。
五.巧用display:none元素:
隱藏元素不會影響不在渲染樹中,對它的任何操作都不會引發重拍或者重繪操作。
所以要對元素進行比較複雜的各種操作時,如果允許的話,可以將其暫時隱藏起來。
操作完畢,再將其顯示出來,這樣只會產生一次重繪和重排操作。
相關文章
- Javascript 效能優化JavaScript優化
- javascript效能優化JavaScript優化
- JavaScript DOM、BOM操作JavaScript
- javascript效能優化(7)JavaScript優化
- javascript效能優化(8)JavaScript優化
- javascript效能優化(9)JavaScript優化
- javascript效能優化(10)JavaScript優化
- 虛擬dom優化效能的表現優化
- 前端效能優化JavaScript篇前端優化JavaScript
- JavaScript基礎之DOM操作JavaScript
- JavaScript5:常用DOM操作JavaScript
- JavaScript操作DOM常用的APIJavaScriptAPI
- 【JavaScript】DOM之樣式操作JavaScript
- JavaScript入門⑦-DOM操作大全JavaScript
- [譯] React效能優化-虛擬Dom原理淺析React優化
- 1.14 JavaScript5:常用DOM操作JavaScript
- JavaScript ----- 操作DOM物件的屬性JavaScript物件
- DOM優化方案優化
- 幾個 JavaScript 效能優化小 TipJavaScript優化
- 淺談JavaScript程式碼效能優化JavaScript優化
- [譯]13 種有用的 JavaScript DOM 操作JavaScript
- JavaScript 前端效能優化之事件防抖JavaScript前端優化事件
- JavaScript 前端效能優化之事件節流JavaScript前端優化事件
- 淺談JavaScript程式碼效能優化2JavaScript優化
- 【前端效能優化】高效能JavaScript讀書筆記前端優化JavaScript筆記
- Spark效能優化:對RDD持久化或CheckPoint操作Spark優化持久化
- js中為什麼dom操作消耗效能JS
- Web 效能優化:理解及使用 JavaScript 快取Web優化JavaScript快取
- 【前端效能優化】vue效能優化前端優化Vue
- JavaScript的字串、陣列以及DOM操作總結JavaScript字串陣列
- 【譯】Web 效能優化:理解及使用 JavaScript 快取Web優化JavaScript快取
- [譯] JavaScript 如何工作:渲染引擎和效能優化技巧JavaScript優化
- DOM操作
- DOM 操作
- 在Angular中操作DOM:意料之外的結果及優化技術Angular優化
- 【零基礎上手JavaWeb】快速上手 JavaScript DOM操作WebJavaScript
- 效能優化優化
- JavaScript 前端效能優化小竅門例項彙總JavaScript前端優化