scroll 事件是一个非常容易被反复触发的事件,另外,resize 事件、鼠标事件(比如 mousemove、mouseover 等)、键盘事件(keyup、keydown 等)都存在被频繁触发的风险。

频繁触发回调导致的大量计算会引发页面的抖动甚至卡顿。为了规避这种情况,我们需要一些手段来控制事件被触发的频率。就是在这样的背景下,throttle(事件节流)和 debounce(事件防抖)出现了。

(闭包形式实现,即返回的是一个函数)

throttle:

// 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:(有定时器)

// fn是我们需要包装的事件回调, delay是每次推迟执行的等待时间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)

用 Throttle 来优化 Debounce

debounce 的问题在于它“可以一等再等”。试想,如果用户的操作十分频繁——他每次都不等 debounce 设置的 delay 时间结束就进行下一次操作,于是每次 debounce 都为该用户重新生成定时器,回调函数被延迟了不计其数次。频繁的延迟会导致用户迟迟得不到响应,用户同样会产生“这个页面卡死了”的观感。

为了避免弄巧成拙,需要借力 throttle 的思想,打造一个“有底线”的 debounce——等待可以,但必须有原则:delay 时间内,可以为不断重新生成定时器;但只要delay的时间到了,必须要给用户一个响应。

// 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)

事件触发控制_前端性能优化:事件的节流throttle与防抖debounce相关推荐

  1. 事件触发控制_基于事件触发机制的直流微电网多混合储能系统分层协调控制方法...

    点击下面标题,了解通知详情第九届电工技术前沿问题学术论坛征文通知 华北电力大学电气与电子工程学院的研究人员郭伟.赵洪山,在2020年第5期<电工技术学报>上撰文,以含有多个混合储能系统(H ...

  2. dll文件懒加载_前端性能优化

    # 前端性能优化 写在最前面:下面都是我对webpack的一些性能优化,想系统的学习性能优化方面的知识 推荐大家看看这本书 很系统 感觉面试也能如鱼得水 ## 构建优化 ### webpack优化 ( ...

  3. 前端白屏问题_前端性能优化之白屏时间

    前言 该篇文章会为您分享在前端性能优化中非常重要的一环-白屏时间,将从白屏时间的概念.重要性以及白屏的过程一一进行阐述,同时提供性能优化的策略与实践. 一.概念 白屏时间:即用户点击一个链接或打开浏览 ...

  4. java接口防抖_前端性能优化:高频执行事件/方法的防抖

    日期:2013-6-25  来源:GBin1.com 高频执行事件/方法的防抖 通常,开发人员会在有用户交互参与的地方添加事件,而往往这种事件会被频繁触发.想象一下窗口的resize事件或者是一个元素 ...

  5. html个人主页_前端性能优化实践 之 百度App个人主页优化

    作者:潘铭 @祝余 前言 性能是每个前端工程师都应该关注的话题,通用的优化手段已有许多文章和实践,就不再赘述,本篇以百度App个人主页为例,聊聊针对业务特点进行的一些性能优化实践. 适用于:传统意义的 ...

  6. vue 图片拖动加载 类似于地图_前端性能优化之图片懒加载(附vue自定义指令)...

    作者:lzg9527 链接:https://juejin.cn/post/6903774214780616718 在类电商类项目,往往存在大量的图片,如 banner 广告图,菜单导航图,美团等商家列 ...

  7. 在dom最前面插入_前端性能优化之dom编程

    写在前面 总所周知,在前端的日常里面,采用JS操作DOM节点的情况占据了大多数.虽然现在有MVVM主流框架代替我们做了这些事情,但充分理解在DOM操作各种损耗问题,将有助于让我们更加理解和优化问题. ...

  8. android 重绘如何能不闪一下屏幕_前端性能优化之重绘和重排

    性能优化中,减少重绘重排应该是一种很好的优化方式,我们具体看一下什么情况下会造成重绘重排,为什么减少重绘重排可以做到优化,怎么样减少重绘重排. 浏览器渲染过程 我们先看看当浏览器拿到服务端返回的资源时 ...

  9. vue 一个页面有点请求需要同时发送_前端性能优化,这些你都需要知道

    来源: 海洋里的魔鬼鱼 前言 最近花了一些时间在项目的性能优化上,背后做了很多工作,但是最后依然没有达到自己想要的结果,有些失望,但是还是记录下自己的执着. 性能优化总结:减少请求次数.减小资源大小. ...

最新文章

  1. 2022年想成为软件测试工程师,这个学习路线收藏起来
  2. 主瓣、栅瓣和旁瓣的定义
  3. 第一个使用Spring Tool Suite(STS)和Maven建立的Spring mvc 项目
  4. (转)学习密度与专注力
  5. css flexbox模型_Flexbox教程:了解如何使用CSS Flexbox编写响应式导航栏
  6. poj-2528线段树练习
  7. c语言gets和getchar区别,c语言中关于getchar()、getchar()和gets().......
  8. java vim ide_把VIM配置成IDE开发环境 | 学步园
  9. opensips mysql 版本_Opensips-1.11版本安装过程
  10. oracle 随机数重复吗,Oracle生成不重复随机数
  11. 7月最新发布10.2.0.4.5 Patch Set Update
  12. keilc error C183: unmodifiable lvalue (编程时要注意啦)
  13. 西工大疫情期间关于如何做好博士学位论文专题讲座笔记
  14. 使用listen()和accept()函数
  15. 红帽考试环境之RHCSA
  16. python 生成式 生成器
  17. 环形电流计算公式_环形电感的计算公式
  18. Tableau可视化项目
  19. 初学者の发送QQ邮箱完整代码
  20. 【新人入门】HTML——前端纯小白新手入门

热门文章

  1. 处理您的请求时发生错误(Web Dynpro ABAP)
  2. 数字时代企业内部如何高效协作?这款工具值得一试
  3. 百雀羚、林清轩、逐本走红背后,植物基护肤品的春天来了?
  4. 亲戚再也看不见我一个人食吉野家了
  5. 导出excel加粗_Python办公自动化|从Word到Excel
  6. linux 生成密码本,Linux下CentOS7使用OTPW实现双因子密码本登录
  7. 陕西师范大学计算机科学学院公寓楼,陕西师范大学计算机科学学院简介
  8. Misc-wireshark-1(秒懂!!)
  9. python取当前时间前后一定间隔的时间点
  10. 广角相机app哪个比较好用_推荐一款比较好用的工作安排备忘app?