網頁dom元素過多爲什麼會導致頁面卡頓

在做移動端或者其他無限下拉加載時會遇到不斷插入dom的場景,隨着dom的增多頁面會出現卡頓,遇到這種情況開發者會採取一系列的優化措施,比如複用dom等,那麼到底爲什麼會出現卡頓呢?本文將探討這個疑問。

網頁卡頓時,瀏覽器進程內存佔用很大,這就說明在卡頓出現的時候,瀏覽器佔用的內存是很大的,如圖:

一個實例:

<body>
    <div id="app"></div>
</body>
<script>
    addDom()
    addDom()
    addDom()
    addDom()
    addDom()
    function addDom(){
        let d = document.createDocumentFragment();
       
        for(var i = 0;i<30;i++){
            let li = document.createElement('li')
            li.addEventListener('click', function(e) {
                let _this = e.target;
                let dom = e.target.tagName.toLowerCase();
                _this.style.color = 'red';
            })
        li.innerHTML = `</div>
            <h4>
                測試圖片 
            </h4>
            <img style = "height:20px;width:100px" src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1591105123139&di=90a63b4962d0b4405ce65c2096a676c2&imgtype=0&src=http%3A%2F%2Fimg0.imgtn.bdimg.com%2Fit%2Fu%3D3769023270%2C3433174748%26fm%3D214%26gp%3D0.jpg"/>
            </div>`
            d.appendChild(li)
        }
        document.getElementById('app').appendChild(d)
    }
</script>

一個下拉加載列表,隨着dom的增加, HEAP SNAPSHOTS逐漸加大,如下圖所示:

那麼到底是哪部分佔用內存增加了呢?

從上面可以看出隨着dom的增加 ,HTMLLIElement佔用的內存逐漸增加,這是由於下拉加載過程中在頁面中添加了LI元素。

shallow size和retained  size

Shallow Size:

Shallow size就是對象本身佔用內存的大小,不包含其引用的對象。

  • 常規對象(非數組)的 Shallow size 由其成員變量的數量和類型決定。
  • 數組的shallow size有數組元素的類型(對象類型、基本類型)和數組長度決定。

Retained Size:

對象的Retained Size = 對象本身的Shallow Size + 對象能直接或間接訪問到的對象的Shallow Size 
也就是說 Retained Size 就是該對象被 GC(Garbage Collection) 之後所能回收內存的總和。

這裏GC是指垃圾回收,瀏覽器的主流垃圾回收機制時標記清除(ie中存在引用計數清除)。

除了dom節點內存增大,監聽事件佔用的內存也逐漸加大

監聽事件的內存也逐漸增大

隨着內存的佔用增大,到一定程度時,網頁就出現了卡頓。

解決辦法:

1,重複利用dom結構,創建虛擬列表

2,使用事件委託,將監聽事件綁定到父元素上

 

參考:

https://www.cnblogs.com/yanglongbo/articles/9762359.html

https://blog.csdn.net/strange_monkey/article/details/81746232

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章