中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Dom節點怎么進行優化

發布時間:2021-04-12 13:05:44 來源:億速云 閱讀:120 作者:小新 欄目:web開發

小編給大家分享一下Dom節點怎么進行優化,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

DOM操作對性能影響最大是因為它導致了瀏覽器的重繪和回流,我們都知道頁面UI的更改都是通過DOM操作實現的,DOM雖然提供了許多api方便我們操作dom,但DOM操作的代價很高,頁面前端代碼的性能瓶頸也大多集中在DOM操作上,所以前端性能優化的一個主要的關注點就是DOM操作的優化。

瀏覽器渲染機制:

Dom節點怎么進行優化
瀏覽器渲染頁面
Dom節點怎么進行優化

  1. 瀏覽器解析 HTML 文檔的源碼,然后構造出一個 DOM 樹,遇到樣式就異步計算。

  2. 異步計算好的樣式與dom樹合成,構建 render 樹。

  3. 進行布局(layout) render 樹。

  4. 進行繪制(painting) render 樹。

DOM樹與render樹的區別在于:樣式為display:none;的節點會在DOM樹中而不在渲染樹中。瀏覽器繪制了之后便開始解析js文件,根據js來確定是否重繪和重排。

回流·重繪

頁面更改發生的操作:

  1. 回流:瀏覽器引擎發現render樹某個節點發生了變化影響了布局,需要倒回去重新渲染,我們稱這個回退的過程叫 回流。回流會從這個root frame開始遞歸往下,依次計算所有的結點幾何尺寸和位置。

  2. 重繪:改變某個元素的背景色、文字顏色、邊框顏色等等不影響頁面dom布局的操作。

js是單線程的,重繪和重排會阻塞用戶的操作以及影響網頁的性能

優化:減少回流重繪次數

1、改變dom多個樣式,使用class,而非style,減少多次觸發回流重繪
舉例:改變dom元素寬高

var dom = document.getElementById('box')
dom.style.width = '300px'
dom.style.height = '300px'//訪問了三次dom,觸發了兩次回流和兩次重繪

優化后:

.change {
    width: 300px;
    height: 300px;
    }
    document.getElementById('p').className = 'change'//只觸發一次

2、列表類型批量修改,脫離文檔流再恢復,利用樣式為display:none;的節點會在DOM樹中而不在渲染樹中不會引起重繪回流。

如果要在一個dom集合中,給每個dom子節點加一個class,我們可以遍歷給每一個節點都加上class,這樣就觸發了多次的重繪和回流

/* //需要加入的樣式
.change {
    width: 300px;
    height: 300px;
}
*/
var ul = document.getElementsByTagName('ul')
var lis = document.getElementsByTagName('li') 
ul.style.display = 'none'
for(var i = 0; i < lis.length; i++) {
    lis[i].className = 'change';
     }
     ul.style.display = 'block'

3、DocumentFragment

虛擬DOM其實就是一個對象,js提供了reateDocumentFragment()方法用于創建一個空的虛擬節點對象,DocumentFragment節點不屬于文檔樹,當需要添加多個dom元素時,如果先將這些元素添加到DocumentFragment中,然后再將DocumentFragment對象添加到渲染樹上,會減少頁面渲染dom的次數,效率會明顯提升。

var frag = document.createDocumentFragment() //創建一個虛擬節點對象	
for(var i = 0; i < 10; i++) {				
    var li = document.createElement("li")		
    li.innerHTML = '我是第' + i + 1 + '個元素'		
    frag.appendChild(li)  //將li元素加到虛擬節點對象上
    } 			
    ul.appendChild(frag)  //將虛擬節點對象加到ul上

其它

1、事件委托,利用瀏覽器事件,冒泡捕獲減少頁面事件綁定,我們可以指定一個事件處理程序就可以管理某一類型的所有事件。事件函數過多會占用大量內存,而且綁定事件的DOM元素越多會增加訪問dom的次數,對頁面的交互就緒時間也會有延遲。

// 事件委托前
var lis = document.getElementsByTagName('li')
for(var i = 0; i < lis.length; i++) {
   lis[i].onclick = function() {
      console.log(this.innerHTML)
   }}    // 利用瀏覽器事件通過父元素委托事件給子元素
   var ul = document.getElementsByTagName('ul')ul.onclick = function(event) {
	//也可以做判斷給指定的子元素綁定事件
   console.log(event.target.innerHTML)};

2、在循環中的優化減少操作dom次數

//例子1:減少在計算過程中操作dom
// 優化前,訪問了好多次dom,這些都是細節問題,有經驗的繞過,小白平常多注意就行
for(var i = 0; i < 10; i++) {
    document.getElementById('el').innerHTML += '1'} 
    // 優化后 
    var str = ''for(var i = 0; i < 10; i++) {
    str += '1'}document.getElementById('el').innerHTML = str/

這樣看獲取你體驗不到緩存節點長度的作用,請看下面的例子

//不緩存
var ps = document.getElementsByTagName("p"), i, p;
for( i=0; i<ps.length; i++ ){  
    p = document.createElement("p");
    document.body.appendChild("p");
    }造成死循環,每次執行for循環都會動態獲取ps的長度,而我們每次進入循環都增加了一個DOM(p),ps的長度也+1.
    //緩存
    var ps = document.getElementsByTagName("p"), i, p,len;
    for( i=0;len=ps.length;i<len; i++ ){  
        p = document.createElement("p");
        document.body.appendChild("p");
    }//使用變量保存ps的長度。

3、選擇器區別

獲取元素最常見的有兩種方法,getElementsByXXX()和queryselectorAll(),這兩種選擇器區別是很大的,前者是獲取動態集合,后者是獲取靜態集合

// 假設一開始有2個livar 
lis = document.getElementsByTagName('li')  // 動態集合
var ul = document.getElementsByTagName('ul')[0]
 for(var i = 0; i < 3; i++) {
    console.log(lis.length)
    var newLi = document.createElement('li')
    ul.appendChild(newLi)}// 輸出結果:2, 3, 4
    // 優化后
    var lis = document.querySelectorAll('li')  // 靜態集合 
    var ul = document.getElementsByTagName('ul')[0]
 for(var i = 0; i < 3; i++) {
    console.log(lis.length)
    var newLi = document.createElement('li')
    ul.appendChild(newLi)}// 輸出結果:2, 2, 2

對靜態集合的操作不會引起對文檔的重新查詢,相比于動態集合更加優化。

以上是“Dom節點怎么進行優化”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節
推薦閱讀:
  1. DOM節點關系
  2. DOM優化

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

dom
AI

镇原县| 锡林郭勒盟| 汨罗市| 资兴市| 白朗县| 阿鲁科尔沁旗| 佛山市| 临桂县| 乐昌市| 汨罗市| 句容市| 巴彦淖尔市| 云龙县| 义马市| 海晏县| 桦南县| 浦县| 益阳市| 古浪县| 昔阳县| 南安市| 宁陵县| 红安县| 东乡族自治县| 南乐县| 鲁甸县| 黑水县| 宣威市| 玉屏| 会理县| 廉江市| 章丘市| 郑州市| 万载县| 黄骅市| 墨脱县| 佛冈县| 峨边| 宜兴市| 佛学| 昌乐县|