网页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

猜你喜欢

转载自blog.csdn.net/qdmoment/article/details/106502972
今日推荐