前端百题斩【021】——通俗易懂的防抖与节流

简介: 前端百题斩【021】——通俗易懂的防抖与节流

性能一直是前端老生常谈的一个话题,其中有一个性能问题就是我们会频繁的触发一些事件,例如mousemove、scroll、resize等,虽然浏览器已经对这些事件的触发做了一些优化,但是如果在很短的时间内频繁的触发仍然会影响性能,这个时候就需要今天的主角:防抖和节流,利用它们来进行优化,提高性能。


21.1 防抖


640.jpg

21.1.1 定义


防抖就是将多次高频操作优化为只在最后一次执行(某个函数在某段时间内,无论触发了多少次回调,都只执行最后一次)。通常的使用场景是:用户输入,只需在输入完成后做一次输入校验即可。


21.1.2 实现


防抖是将多次操作合并为一次操作完成,其原理就是维护一个计时器,在规定的时间后触发函数,但是在该规定时间内再次触发的话就会取消之前的定时器而重新设置,从而保证了只有最后一次操作能够被触发。其实现步骤如下所示:


  1. 利用闭包保存一个timer变量,然后返回一个函数(这个返回的函数就是后续频繁触发操作中调用的函数);
  2. 根据标志位判断是否第一次需要立即执行(因为有些情况是需要首次调用函数立即执行的,若没有该参数,就会在定时器到了之后才会执行);
  3. 当有新的触发时,若存在定时器,则清空该定时器;
  4. 设定一个新的定时器,重新计时。


function debounce(fn, wait, immediate) {
        let timer = null;
        return function (...args) {
            // 立即执行的功能(timer为空表示首次触发)
            if (immediate && !timer) {
                fn.apply(this, args);
            }
            // 有新的触发,则把定时器清空
            timer && clearTimeout(timer);
            // 重新计时
            timer = setTimeout(() => {
                fn.apply(this, args);
            }, wait);
        }
    }


21.1.3 效果预览

640.gif




观察效果图可以验证上述的理论知识:


  1. 防抖之后输出内容的频次降低了;
  2. 防抖之后,其在超过一定时间之后才会输出内容。


21.2 节流



640.jpg


21.2.1 定义


节流就是每隔一段时间后执行一次,也就是降低频率,将高频操作优化成低频操作。通常使用场景:滚动条事件、resize事件、动画等,通常每隔100-500ms执行一次即可。


21.2.2 实现


节流函数的实现方式有两种:定时器版本、时间戳版本,这两者各有千秋,下面来简要实现一下。


21.2.2.1 定时器版本


定时器版本的节流函数其重点是利用闭包保存timer变量,具有两个特点:

  1. n秒后才会执行第一次(定时器到了时间后才会触发);
  2. 停止触发后节流函数还会执行一次(因为该函数是延迟执行的,当停止触发时其任务已经到了队列中,所以停止后还会执行一次)。


// 定时器版本
function throttle(fn, wait) {
    let timer = null;
    return function(...args) {
        if (!timer) {
            timer = setTimeout(() => {
                fn.apply(this, args);
                timer = null;
            }, wait)
        }
    }
}


21.2.2.2 时间戳版本


时间戳版本的节流函数重点是利用闭包保存上一次的时间previous,具有两个特点:

  1. 开始触发后会立即执行(因为previous开始会被赋值为0);
  2. 停止触发后不再执行(因为该函数是同步任务,在触发的时候就会进行相应的判断,所以就不存在停止触发后再执行的情况)。
// 时间戳版本
function throttle(fn, wait) {
    // 上一次执行时间
    let previous = 0;
    return function(...args) {
        // 当前时间
        let now = +new Date();
        if (now - previous > wait) {
            previous = now;
            fn.apply(this, args);
        }
    }
}


21.2.3 效果预览

640.gif

观察效果图可以验证上述的理论知识:


  1. 节流确实降低了内容的输出频率,将高频变为低频;
  2. 时间戳版本的节流函数在首次会输出内容,但是最后一次的内容不会输出(谨慎使用);
  3. 定时器版本的节流函数确实不会立刻打印内容,而是超过一定时间之后才会打印;此外,其最后输入的内容会被打印出来。
相关文章
|
4天前
|
前端开发 JavaScript API
|
4天前
|
前端开发 JavaScript UED
【前端面经】快手二面:节流和防抖知道吗?
【前端面经】快手二面:节流和防抖知道吗?
6 0
|
4天前
|
前端开发 UED
【Web 前端】防抖与节流的区别
【4月更文挑战第22天】【Web 前端】防抖与节流的区别
|
4天前
|
前端开发 JavaScript UED
【专栏】前端开发中,为解决用户操作引发的性能问题,常使用debounce(防抖)和throttle(节流)技术
【4月更文挑战第29天】前端开发中,为解决用户操作引发的性能问题,常使用debounce(防抖)和throttle(节流)技术。Debounce确保在一段时间内只执行最后一次事件触发的操作,减少不必要的执行,但有滞后性,适合搜索框实时搜索。Throttle则保证一定时间间隔内函数执行一次,保持固定频率,适用于滚动事件处理和窗口大小调整。两者可借助JavaScript或第三方库实现,需根据场景和需求选择并调整。正确使用能提升应用性能和用户体验。
|
4天前
|
Web App开发 JavaScript 前端开发
【Node.js】大前端技能最通俗易懂的讲解 快速入门必看
【Node.js】大前端技能最通俗易懂的讲解 快速入门必看
37 0
|
4天前
|
前端开发
【前端学习】—函数防抖(十)
【前端学习】—函数防抖(十)
|
7月前
|
前端开发
前端性能优化之防抖&节流
前端性能优化之防抖&节流
41 0
|
8月前
|
监控 前端开发
前端经典面试题 | 理解 节流 和 防抖(后附手写节流\防抖)
前端经典面试题 | 理解 节流 和 防抖(后附手写节流\防抖)
|
11月前
|
存储 前端开发 JavaScript
【前端常见面试题】防抖与节流
简介: 在前端开发中,防抖和节流是两个常见的概念,用于处理频繁触发的事件或函数。之前整理防抖与节流的文章,但是细节不全,本文将详细解释防抖和节流的概念,以及应用场景,并提供实际代码示例,帮助更好地理解和掌握这两个常见的前端面试题。
95 1
【前端常见面试题】防抖与节流
|
2天前
|
移动开发 前端开发 JavaScript
10款精美的web前端源码的特效,2024年最新面试题+笔记+项目实战
10款精美的web前端源码的特效,2024年最新面试题+笔记+项目实战