当前位置: 首页 > Web前端 > HTML

Vue中的事件防抖和节流

时间:2023-04-03 00:53:23 HTML

喜欢再看,微信搜索【伟大的走向世界】关注这个没有大厂背景,但心态向上积极的人.本文已收录到GitHubhttps://github.com/qq44924588...,文章已分类,也整理了很多我的文档和教程资料。大家都说简历里没项目可写,所以给大家找了一个项目,还给了一个【搭建教程】。某些浏览器事件可以在短时间内快速触发多次,例如调整窗口大小或向下滚动页面。比如监听一个页面窗口滚动事件,如果用户一直快速向下滚动页面,那么滚动事件可能会在3秒内触发数千次,这可能会导致一些严重的性能问题。如果您在面试中讨论构建应用程序,请务必提及去抖动和节流,以在发生滚动、窗口大小调整或按键等事件时提高页面速度和性能。这两兄弟的本质是以闭包的形式存在的。通过包装事件对应的回调函数,以自由变量的形式缓存时间信息,最后通过setTimeout来控制事件的触发频率。油门:先人说了算。Throttle的中心思想是:在一定时间内,不管你触发了多少回调,我只认第一次,计时结束时响应。先给大家讲个小故事:现在有个旅客刚下飞机,需要用车,就叫了机场唯一的机场大巴来接。司机把车开到机场,心想大家都来了,还是多接几个人一起走吧,这样不虚此行——我等十分钟看看。于是司机就打开了定时器,招呼着后面的客人陆续上车。在这十分钟内,下飞机的乘客只能乘坐这趟车。十分钟过去了,不管后面还有多少乘客没有挤上车,这辆公交车都必须被送走。在这个故事中,“司机”是我们的节流阀,它控制着出发的时机;“乘客”是因为我们频繁的操作事件而不断涌入的回调任务,需要接受“司机”的安排;“设备”就是前面提到的自由变量形式的时间信息,是“司机”决定启动汽车的依据;“启动汽车”的最后一个动作对应回调函数的执行。综上所述,所谓“节流”就是通过在一段时间内忽略后续的回调请求来实现的。只要有客户叫车,司机就会为他启动定时器。在一定时间内,所有需要坐车的客人都要排队上这辆车,谁也不能叫多车。对应到实际的交互也是一样的:用户每触发一次滚动事件,我们就为这次触发操作启动定时器。有一段时间,所有后续滚动事件都被视为“车上的乘客”——它们无法触发新的滚动回调。直到“一段时间”到来,第一次触发的scroll事件对应的回调会被执行,后续“一段时间内”触发的scroll回调会被throttle忽略。现在一起实现一个throttle://fn是我们需要包裹的事件回调,interval是时间间隔函数的阈值throttle(fn,interval){//last是上次触发回调的时间letlast=0//处理throttle结果以函数形式返回returnfunction(){//调用时保留this上下文letcontext=this//调用时保留传入的参数letargs=arguments//记录调用时的时间本次触发回调letnow=+newDate()//判断上次触发时间与本次触发时间的时间差是否小于时间间隔的阈值if(now-last>=interval){//如果时间间隔大于我们设置的时间间隔阈值,则执行回调last=now;fn.apply(上下文,参数);}}}//使用throttle来包裹滚动回调constbetter_scroll=throttle(()=>console.log('scrolleventtriggered'),1000)Debounce:最后一个人说了算反的中心思想摇是:我会等你到最后。一定时间内,不管你触发多少次回调,我只认最后一次。继续司机开车的故事。这次司机更有耐心了。第一位乘客上车后,司机启动计时器(比如十分钟)。十分钟内,如果有另一位乘客上来,司机将重置计时器并开始再等待十分钟(延迟等待)。直到有这样一位乘客,自从他上车后,接下来的十分钟内没有新的乘客上车,司机就会认为没有人需要坐这辆公交车,就会把车开走。我们通过对比throttle来理解debounce:在throttle的逻辑中,“先人说??了算”,它只为第一个乘客统计时间,时间到了就执行回调。而debounce认为“最后的人说了算”,debounce会为每一个新乘客设置一个新的定时器。现在一起实现一个debounce://fn是我们需要包装的事件回调,delay是每次延迟执行的等待时间函数返回returnfunction(){//调用时保留this上下文letcontext=this//调用时保留传入的参数letargs=arguments//每次触发事件,清除之前的旧定时器if(timer){clearTimeout(timer)}//创建一个新的定时器timer=setTimeout(function(){fn.apply(context,args)},delay)}}//使用debounce包装滚动回调constbetter_scroll=debounce(()=>console.log('scrolleventtriggered'),1000)使用Throttle优化Debouncedebounce的问题在于它“太有耐心”。试想一下,如果用户的操作非常频繁——他并没有等到debounce设置的延迟时间结束再进行下一个操作,那么debounce每次都为用户重新生成定时器,回调函数就被延迟了无数次。频繁的延迟会导致用户长时间得不到响应,用户也会产生“这个页面卡住了”的印象。为了避免弄巧成拙,我们需要用throttle的思想来制造一个“底线”debounce——你可以等,但我有我的原则:在延迟时间内,我可以为你重新生成定时器;但是只要延迟到时候,我就得给用户一个响应。这种“整合”throttle和debounce的思路已经被很多成熟的前端库应用到他们增强版throttle函数的实现中://fn是我们需要包装的事件回调,delay是的阈值时间间隔functionthrottle(fn,delay){//last为上次触发回调时间,timer为定时器letlast=0,timer=null//将节流处理结果作为函数返回returnfunction(){//调用时保持this上下文letcontext=this//保持调用时传入的参数letargs=arguments//记录本次触发回调的时间letnow=+newDate()//判断是否有区别上次触发的时间和本次触发的时间小于时间间隔阈值if(now-lastconsole.log('scrolleventtriggered'),1000)document.addEventListener('scroll',better_scroll)在Vue中使用lodash中的Debouncing和Throttling事件Throttling和debounce是提高性能或减少网络开销的好方法。虽然之前Vue1支持对事件进行节流和防抖,但是在Vue2中,为了保持核心简单,删除了对事件的节流和防抖的支持。因此,我们可以使用lodash来对Vue2中的事件进行去抖和节流。安装Lodash可以通过yarn或npm安装。#Yarn$yarnaddlodash#NPM$npminstalllodash--save注意:如果我们不想从lodash导入所有东西,而只导入我们需要的部分,一些Webpack构建定制可以解决这个问题。也可以使用lodash.throttle和lodash.debounce等包单独安装和导入部分lodash。throttling方法对事件进行throttle非常简单,只需要将要调用的函数包裹在lodash的_.throttle函数中即可。去抖动方法虽然节流在某些情况下有用,但一般我们经常使用的是防抖.Debounce基本上将我们的事件组合在一起,并防止它们被过于频繁地触发。要在Vue组件中使用节流,只需将要调用的函数包装在lodash的_.debounce函数中即可。代码部署后,不可能真正知道可能的错误时间。为了解决他们事后的BUG,我花了很多时间在日志调试上。顺便推荐一个好用的BUG监控工具,Fundebug。参考:ThrottlingandDebouncinginJavaScriptTheDifferenceBetweenThrottlingandDebouncingThrottlingandDebouncingExamplesRemySharp的博文Throttlingfunctioncalls前端性能优化原理与实践交流文章每周持续更新,微信搜索【大千世界】即可阅读和阅读马上回复【福利】有很多前端视频等着你。本文GitHubhttps://github.com/qq449245884/xiaozhi已收录。欢迎来到星空。