性能优化: 手写防抖、节流

2021-02-01 09:45发布

手写防抖,节流

原则:

  1. 多使用内存,缓存或其他方法

  2. 减少cpu计算量,减少网络加载耗时

让加载更快,渲染更快,减少资源体积。减少访问次数,合并代码,ssr服务器端渲染,缓存。

dom查询进行缓存,频繁dom操作,合并到一起插入dom结构,节流throttle防抖debounce

服务器端渲染,讲网页和数据一起加载,一起渲染

非ssr,先加载网页,再加载数据,再渲染数据

懒加载

代码:

<img id="img1" src="preview.png" data-realsrc="abc.png"/>
<script type="text/javascript">
    var img1 = document.getElementById('img1');
    img1.src = img1.getAttribute('data-realsrc');
</script>

防抖debounce

  1. 监听一个输入框,文字变化后触发change事件

  2. 直接用keyup事件,则会频繁触发change事件

防抖,用户输入结束或暂停时,才会触发change事件。

代码:

const input1 = document.getElementById('input1');
input1.addEventListener('keyup', function(){    
    console.log(input1.value);
}};

代码:

const input1 = document.getElementById('input1');
let timer = null;
input1.addEventListener('keyup', function(){    
    if(timer) clearTimeout(timer);
    timer = setTimeout(()=>{        // 模拟触发change事件
        console.log(input1.value)        // 清空定时器
        timer = null
    },500);
});

debounce防抖代码:

function debounce(fn, delay = 500) {    
    // timer 是闭包中的
    let timer = null;
    return function() {        
        if(timer) {            
            clearTimeout(timer);
        }
        timer = setTimeout(()=>{
            fn.apply(this, arguments);
            timer = null;
        },delay);
    };
};

input1.addEventListener('keyup', debounce(()=>{    
    console.log(input1.value);
}),600);

节流throttle

拖拽一个元素时,要随时拿到该元素被拖拽的位置

代码:

const div1 = document.getElementById('div1');
let timer = null;
div1.addEventListener('drag',function(e){    
    if(timer){        
        return
    }
    timer = setTimeout(()=>{        
        console.log(e.offsetX, e.offsetY);
        timer = null;
    },100);
});

节流代码:

function throttle(fn, delay = 100) {    
    let timer = null;
    return function() {        
        if(timer) {            
            return;
        }
        timer = setTimeout(()=>{
            fn.applay(this,arguments);
            timer = null;
        },delay);
    };
};

div1.addEventListener('drag',throttle(function(e){    
    console.log(e.offsetX,e.offsetY);
},200));