js 高程 22.3.3章节 里看到了 函数节流 的概念,觉得给出的代码可以优化,并且概念理解可以清晰些,所以总结如下:

先看 函数节流 的定义,书上原话(斜体表示):

产生原因/适用场景:

浏览器中某些计算和处理要比其他的昂贵很多。例如,DOM 操作比起非 DOM 交互需要更多的内存和 CPU 时间。连续尝试进行过多的 DOM 相关操作可能会导致浏览器挂起,有时候甚至会崩溃。尤其在 IE 中使用onresize 事件处理程序的时候容易发生,当调整浏览器大小的时候,该事件会连续触发。
在onresize 事件处理程序内部如果尝试进行 DOM 操作,其高频率的更改可能会让浏览器崩溃。为了绕开这个问题,你可以使用定时器对该函数进行节流。

基本思想:

函数节流背后的基本思想是指,某些代码不可以在没有间断的情况连续重复执行。第一次调用函数,创建一个定时器,在指定的时间间隔之后运行代码。当第二次调用该函数时,它会清除前一次的定时器并设置另一个。如果前一个定时器已经执行过了,这个操作就没有任何意义。然而,如果前一个定时器尚未执行,其实就是将其替换为一个新的定时器。目的是只有在执行函数的请求停止了一段时间之后才执行。

我的理解:

譬如 onresize 和 onmouseover 事件,在 缩放浏览器 和 鼠标滑过 时,是不间断触发的,仅仅是 缩放下浏览器 和 滑过鼠标 这个看似简单的动作,其实已经触发了 n 次 onresize 和 onmouseover 事件了,如果绑定的事件处理程序又有点复杂,那这个 n 次执行时很耗资源的;

举例:

function mouseoverConsole() {
console.log('mousemove');
}
document.onmouseover = mouseoverConsole;

这个代码很简单,如果我们鼠标滑过下文档,你会发现:

仅仅是滑下,这个 mouseoverConsole 就执行了 13次,如果用户滑过的次数多些,时间久些,那么这个 mouseoverConsole 就会执行更多次,如果这个函数本身不耗资源也就算了,如果很耗资源呢,那就可能造成页面卡顿;

再举个例子,onresize 事件,可能会造成浏览器重新计算布局,如果布局很复杂,在缩放浏览器的时候,onresize 事件又在不断触发,就可能造成浏览器卡顿,虽然用户缩放浏览器可能只用了1s不到,但是触发了 onresize 事件可能有20次,然而 onrsize 触发的第一次事件处理程序可能还没执行完,而后面还有 19 次需要执行,自然就会卡顿;

那么如果说,第一次的还在执行或还没执行,在 100ms 内又触发了 9 次,那么实际上,直接执行第 10 次的事件处理程序就可以了,因为,100ms 内页面调整 10 次 和调整 1 次,用户是区分不出来的,但是运行 10 次 和 1 次对于浏览器而言所耗资源是不一样的,尤其是事件处理程序复杂时;这就是我理解的 函数节流 的思想;

函数节流优点:

节省资源,案例见上例子;

函数节流缺点:

效果延时,动态效果受影响,不过可以通过缩短间隔时间来优化解决,比如 100ms 改成 10ms;

譬如,极端点,如果用户一直在不停滑鼠标,中间 100ms 都没有停过,那么根据函数节流的思想,绑定的事件处理程序就一直不会执行,直到,用户停下来有 100ms 的时间才会开始执行绑定的事件处理程序;就像你缩放浏览器一直没停,那么页面就会在你停下来的时候才会调整,自然你就看不到中间缩放时页面的变化;

因为第 2 次触发会把第一次的事件处理程序停掉,第 3 次的停第 2 次的,一直到中间停下来 100ms ,那么当次的事件处理程序才会执行;当然如果把 100ms 改成 10ms ,缺点就会降低,当然所占资源就会增加,所以中间的间隔时间提供了一个选择,可以修改间隔时间来平衡性能和效果;

下面来上代码,书上代码,关于 apply() ,arguments 不明白的看 这里

普通代码,不进行函数节流:

window.onresize = function() {
var div = document.getElementById("myDiv");
div.style.height = div.offsetWidth + "px";
};

函数节流代码:

window.onresize = function() {
throttle(resizeDiv);
}; function throttle(method, context) {
clearTimeout(method.tId);
method.tId = setTimeout(function() {
method.call(context);
}, 100);
} function resizeDiv() {
var div = document.getElementById("myDiv");
div.style.height = div.offsetWidth + "px";
}

这里,调整大小的功能被放入了一个叫做 resizeDiv() 的单独函数中。然后onresize 事件处理程序调用throttle()并传入 resizeDiv 函数,而不是直接调用 resizeDiv()。多数情况下,用户是感觉不到变化的,虽然给浏览器节省的计算可能会非常大。

只要代码是周期性执行的,都应该使用节流,但是你不能控制请求执行的速率。这里展示的 throttle() 函数用了 100ms 作为间隔,你当然可以根据你的需要来修改它。

我自己优化了下,这样调用的时候更简单,可以直接设置 时间间隔(平衡性能和展示),且可以传递 event 对象;

document.onmouseover = throttle(mouseoverConsole,100);

function throttle(method,interval,context) {
return function() {
var args = arguments;
clearTimeout(method.timeoutId);
method.timeoutId = setTimeout(function() {
method.apply(context, args);
}, interval);
};
} function mouseoverConsole(event) {
console.log(event.type);
}

最新文章

  1. Oracle使用SQL传输表空间
  2. JS+CSS3人物奔跑动画
  3. Spring boot 学习记录
  4. TAP/TUN摘要
  5. java中FileInputStream和FileOutputStream对图片操作的例子
  6. D3.js 理解 Update、Enter、Exit
  7. IIS问题汇总
  8. ajax异步传输
  9. Nagios监控的部署与配置
  10. Python中 sys.argv[]的用法简明解释
  11. DWR使用总结
  12. [Android] Android 使用 Greendao 操作 db sqlite(1)-- 直接在MainActivity中调用
  13. GLSL版本的区别和对比
  14. C#改变图片大小
  15. AtCoder Regular Contest 094 D Worst Case
  16. B+树和LSM比较(转)
  17. UVA 10815:Andy's First Dictionary(STL)
  18. Idea代码可视化插件
  19. charles工具过滤腾讯视频播放器广告
  20. 数据结构与算法之排序(2)选择排序 ——in dart

热门文章

  1. Atitit.404错误解决标准流程and url汉字中文路径404错误resin4 resin chinese char path 404 err解决
  2. 线程相关函数(6)-pthread_cond_wait(),pthread_cond_signal(), 条件变量
  3. python-爬图小样
  4. :-1: error: [debug/moc_gotocelldialog.cpp] Error 2
  5. 悦铃文件必须是CCITT A_Law格式的,且没有被压缩
  6. nodejs具体解释
  7. 演练:创建和注册自定义 HTTP 模块
  8. PHP——数组中的each(),list()和while循环遍历数组
  9. VIM打开shell脚本中文乱码解决
  10. 29个酷炫的Firefox配置参数