前言
我们在日常开发中,经常会遇到处理系统高频回调的问题,比如:scrollView 快速滚动的回调(scrollViewDidScroll),又比如用户输入文本时textView的回调(textViewDidChange),在这些场景下,为了降低CPU负担,我们一般会使用一些方法降低高频次计算,这篇文章介绍解决高频次计算的两种方法:防抖(debounce) 和 节流(throttle)。
实际工作中这两者如果搞混了,会十分影响用户的体验。
防抖(debounce)
首先提出第一种思路,防抖:在第一次触发事件时,不立即执行函数,而是给出一个期限值比如200ms,然后:
-
如果在200ms内,事件再次触发,当前的计时取消,重新开始计时
-
如果在200ms内,事件没有触发,那么执行事件的处理函数
效果:指定时间内连续触发事件,只在最后一次事件触发结束后的指定时间之后,执行一次处理函数。
节流(throttle)
当事件第一次触发的时候,也是不立即执行函数,而是给出一个期限值比如200ms,开始计时,然后
-
在200ms内,再次触发的事件被全部忽略,计时结束后,执行一次函数,并且清理计时器。
-
200ms结束后,重新开始上述循环
效果:如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效。
小结
防抖和节流是两种解决短时间事件触发频率过高问题的思路,防抖是动态的,只有当最后一次事件触发结束之后,才会执行处理函数。中间没有处理过函数,防止了页面"抖动",可以认为保证了过程的连续平滑。
而节流是离散的,明确对时间进行了分割,在指定的时间块中只执行一次事件处理函数。
思考题
看起来防抖和节流都能解决高频回调的问题,那我们什么时候使用防抖(debounce),什么时候使用节流(throttle)呢?
首先,从降低CPU计算频次来说,肯定是 debounce 效果更好,因为它在整个高频回调期间,只会触发一次。
但 debounce 计算频次少,带来的影响就是可能会损失用户的体验。比如如果在 scrollViewDidScroll 中使用了 debounce 来触发某些渲染逻辑,那么用户如果一直在滚动屏幕,只有在用户松手后,才能把屏幕渲染出来,整个滚动过程是无法加载的。
考虑到现在CPU计算能力越来越强,在解决高频回调问题面前,我们可以优先选择 throttle 的方案。结合我自己所做项目的经历,无论是解决 scrollViewDidScroll 问题,还是解决 textViewDidChange 问题,都是优先采用 throttle 的方案。
网友评论