前端性能优化:节流、防抖

节流

  1. 何为节流?
    定义:节流 (throttle): 高频事件在规定时间内只会执行一次,执行一次后,只有大于设定的执行周期后才会执行第二次。
    也就是说,让需要频繁触发的事件按照指定的时间间隔进行多次触发

  2. 什么时候需要用?
    从性能优化的角度考虑,不需要那么高频的触发,需要限制一下时, 可使用节流

应用场景有:

  • DOM 元素的拖拽功能实现(mousemove);

  • 射击游戏的 mousedown/keydown 事件(单位时间只能发射一颗子弹);

  • 计算鼠标移动的距离(mousemove);

  • Canvas 模拟画板功能(mousemove);

  • 搜索联想(keyup);

  • 监听滚动事件判断是否到页面底部自动加载更多:给 scroll 加了 debounce 后,只有用户停止滚动后,才会判断是否到了页面底部;如果是 throttle 的话,只要页面滚动就会间隔一段时间判断一次。

  1. 实现代码
// 你要多次触发的函数
const fn = function() {
    console.log('scroll')
};
// 节流函数
function throttle(fn, time) {
    let timer = null;
    let startTime = new Date();  // 初始调用的时间
    return function () {
        let args = [].slice.call(arguments);
        // 当前的时间 - 开始时间 是否大于指定的时间差
        timer = (new Date() - startTime) >= time;  
        if (timer) {
            fn.apply(this, args);
            startTime = new Date();
        }
    }
}
const f = throttle(fn, 300);
//window.onscroll = fn;
window.onscroll = f;

防抖

  1. 何为防抖?
    定义: 防抖 (debounce): n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间。
    也就是说,事件是需要可多次触发的, 但只有在距离上次触发的时间大于指定时间时,才会触发事件(在指定时间只允许执行一次)

  2. 什么时候需要用?
    应用场景有 :
    ①窗口的resize
    ②当输入框input输入时需要进行联想时,我们会监听keyup事件,更可能需要调用联想词的接口,这时我们该思考了,真的需要每按一个按键就触发一次调用联想词吗?实际上是不需要的,用户迅速的输入时,就频繁的调接口是一种浪费。使用防抖,可以限制一个方法在一定时间内执行的次数,有效的提高了网站性能
    ③一个元素的onmouseover事件,或滚动事件,或其他执行得非常迅速的高频触发事件

  3. 实现代码

const fn = function() {
    console.log('scroll')
};
// 防抖函数
function debounce(fn, time) {
    let timer = null;
    return function () {
        var _this = this;
        let args = [].slice.call(arguments);
        clearTimeout(timer)
        timer = setTimeout(function () {
            fn.apply(_this, args);
        }, time)
    }
}
window.onscroll = debounce(fn, 300);

你可能感兴趣的:(前端性能优化)