前端性能优化提升

前端性能优化(一)——浅谈节流与防抖

前言

本着总结、自我提高为目的,整理了下自己认知的前端性能优化方面的方式方法。本文主要介绍最普遍的优化之一 ——节流和防抖。

使用背景

频繁触发回调导致的大量计算会引发页面的抖动甚至卡顿。为了规避这种情况,我们需要一些手段来控制事件被触发的频率。
无论是节流还是防抖,都是以“闭包“的形式存在,以自由变量的形式缓存时间信息,最后用 setTimeout 来控制事件的触发频率

Throttle(节流)

所谓节流,可以理解成第一个人说得算,在一定时间内无论你触发多少次函数,我都以第一次触发为标准,并且在时间结束后给予反馈。话不多说,以scroll事件为例,直接看代码!

// fn是我们需要包装的事件回调, interval是时间间隔
function throttle(fn, interval) {
  // last为上一次触发回调的时间
  let last = 0
  // 将throttle处理结果当作函数返回
  return function () {
      // 保留调用时的this上下文
      let context = this
      // 保留调用时传入的参数
      let args = arguments
      // 记录本次触发回调的时间
      let now = +new Date()
      
      // 判断上次触发的时间和本次触发的时间差是否小于时间间隔的阈值
      if (now - last >= interval) {
      // 如果时间间隔大于我们设定的时间间隔阈值,则执行回调
          last = now;
          fn.apply(context, args);
      }
    }
}
// 用throttle来包装scroll的回调
const better_scroll = throttle(() => console.log('触发了滚动事件'), 1000)
document.addEventListener('scroll', better_scroll)

总结下来,所谓节流就是在一段时间内无视后来产生的回调请求

Debounce(防抖)

所谓防抖,就是像是一个“傻瓜”,*它会一直等你到底。也就是在一段时间内,不管你触发了多少次回调,我都只认最后一次。 还是以最scroll事件为例,直接看代码

function debounce(fn, delay) {
  // 定时器
  let timer = null
  
  // 将debounce处理结果当作函数返回
  return function () {
    // 保留调用时的this上下文
    let context = this
    // 保留调用时传入的参数
    let args = arguments

    // 每次事件被触发时,都去清除之前的旧定时器
    if(timer) {
        clearTimeout(timer)
    }
    // 设立新定时器
    timer = setTimeout(function () {
      fn.apply(context, args)
    }, delay)
  }
}

// 用debounce来包装scroll的回调
const better_scroll = debounce(() => console.log('触发了滚动事件'), 1000)

document.addEventListener('scroll', better_scroll)

节流+防抖

防抖是有些问题的,问题就在于它“太傻”了。只能痴痴地等待。我们可以用节流去优化一下防抖。同样是以scroll 为例,看代码

// fn是我们需要包装的事件回调, delay是时间间隔的阈值
function throttle(fn, delay) {
  // last为上一次触发回调的时间, timer是定时器
  let last = 0, timer = null
  // 将throttle处理结果当作函数返回
  
  return function () { 
    // 保留调用时的this上下文
    let context = this
    // 保留调用时传入的参数
    let args = arguments
    // 记录本次触发回调的时间
    let now = +new Date()
    
    // 判断上次触发的时间和本次触发的时间差是否小于时间间隔的阈值
    if (now - last < delay) {
    // 如果时间间隔小于我们设定的时间间隔阈值,则为本次触发操作设立一个新的定时器
       clearTimeout(timer)
       timer = setTimeout(function () {
          last = now
          fn.apply(context, args)
        }, delay)
    } else {
        // 如果时间间隔超出了我们设定的时间间隔阈值,那就不等了,无论如何要反馈给用户一次响应
        last = now
        fn.apply(context, args)
    }
  }
}

// 用新的throttle包装scroll的回调
const better_scroll = throttle(() => console.log('触发了滚动事件'), 1000)

document.addEventListener('scroll', better_scroll)

小节

正好最近刚换好工作, 越发发现性能优化方面,尤其是节流防抖已经成为前端面试的高频考点。我觉得本文写到的代码,除了要看懂、理解过程外,最重要的是要在平时开发中进行应用。用了之后,我相信你会感叹道:“嗯,真香。”
我就是我,全网最菜的前端——痴心。有缘下次更新见。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值