JavaScript性能优化技巧之函数节流
来源:互联网 发布:mysql 重命名字段 编辑:程序博客网 时间:2024/06/05 18:52
在写上一篇获取宽高度的博客的时候发现了一个问题,设置了$(window).resize()
和$(window).scroll()
的时候,函数调用的次数特别频繁,因为我写博客只是为了展现一个简单的例子,所以函数特别简单,但是当函数比较复杂的时候,那么频繁的调用这个函数将会对性能有特别大的损耗。
再写了简单的例子展现一下这个问题吧:
var n = 1;$(window).resize(function(){ console.log(n++);});
看一下运行的效果:
这是刚运行时候的界面:
下面是我简单的调整了一下浏览器的宽度:
在上面的例子中可以看出,这是简单的调整了一下窗口的位置,$(window).resize()
方法就执行了96次,如果函数很复杂的话那么网页性能将会有极大的损耗,现在我们想要的是在调整页面之后执行一两次就行了,只要在调整完浏览器大小之后数据显示正确就可以了。
下面要介绍一种方法,叫做函数节流,函数节流的思想就是设置一个定时器,阻断连续执行的函数。
下面我们来简单的实现一下这个方法:
var n = 1;var throttle = null;$(window).resize(function(){ clearTimeout(throttle); throttle = setTimeout(function(){ console.log(n++); },500);});
然后我再次调整浏览器的宽度:
可以看出来,通过上面的方法在调面后$(window).resize()
方法只执行了整页一次。
接下来的任务就是把函数节流的方法封装一下,使它在任何地方都可以调用。
//封装函数function throttle(method,context){ clearTimeout(method.throttle); method.throttle = setTimeout(function(){ method(); },500);}//调用它$(window).resize(function(){ throttle(lg,window);});var n = 1;function lg(){ console.log(n++);}
这样就可以在任意地方使用这个函数了,如果要自己设置延迟时间的话也可以修改函数自定义延迟时间,如下:
//封装函数function throttle(method,context,time){ clearTimeout(method.throttle); method.throttle = setTimeout(function(){ method(); },time);}//调用它var n = 1;$(window).resize(function(){ throttle(lg,window,300);});function lg(){ console.log(n++);}
这样的做法简单高效,但是有一点不好的是它拓展了函数的属性,如果函数存在这个属性的话那么就会造成这个函数改变,还有一种使用闭包的方法来实现函数节流。
//封装函数function throttle(method,delay){ var timer = null; return function(){ clearTimeout(timer); var context = this, args = Array.prototype.slice.call(arguments); timer = setTimeout(function(){ method.apply(context,args); },delay); }}//调用它 //这里需要注意一下,因throttle()的返回值是一个函数,所以不能$(window).resize(function(){throttle(lg,window,300);})这样调用//要直接将throttle当做函数赋给一个事件,像下面这样$(window).resize(throttle(lg,300));var n = 1;function lg(){ console.log(n++);}
上面两种方法都有各自的好处,具体想用哪种看自己的爱好。
在这种函数节流的情况下,拿窗口大小调整作为例子来说一下,如果我设置的延缓值为500毫秒,如果我调整浏览器大小的频率在500毫秒以内,那么这个函数就一直不会调用,每次延缓500毫秒,在还没有执行的时候我又调整了浏览器大小,那么js就会取消上一次setTimeout()
设置的函数,重新设置一次新的setTimeout()
在500毫秒之后执行,这样虽然做到了阻断连续重复的函数,但是函数却一直不能执行,这时候我们可以再做一次修改,让函数在触发以后在固定的时间内触发,即调整浏览器大小以后不管500毫秒以内你有没有再调整浏览器的大小,我们都让它在500毫秒后执行上次设置的函数,如果不断的改变浏览器大小,它就会每隔500毫秒执行一次,在很多时候是有这样的需求的,现在我们来更改一下上面的代码让它实现这样的需求。
//封装函数function throttle(method,delay,duration){ var begin = new Date(); var timer = null; return function(){ var current = new Date(), args = Array.prototype.slice.call(arguments), context = this; clearTimeout(timer); if(current - begin >= duration){ method.apply(context,args); begin = current; }else{ timer = setTimeout(function(){ method.apply(context,args); },delay); } }}//调用这个方法$(window).resize(throttle(lg,2000,2000));var n = 1;function lg(){ console.log(n++);}
使用上面这个方法测试以后,发现只要在设置的固定间隔之后就会执行一次,不会出现一直不执行的情况。
- JavaScript性能优化技巧之函数节流
- JavaScript性能优化技巧之函数节流
- JavaScript 性能优化技巧:函数节流
- Javascript性能优化之 函数节流技术
- js性能优化之函数节流
- JS性能优化 -- 函数节流
- 高级技巧之函数节流
- JavaScript-性能优化,函数节流(throttle)与函数去抖(debounce)
- javascript之jQuery 性能优化技巧
- JavaScript性能优化之小技巧
- JavaScript 函数节流
- javascript的函数节流
- javascript 函数节流
- 【JavaScript】函数节流
- JavaScript中的函数节流
- javascript函数节流
- javascript的函数节流
- Javascript函数节流
- Interllij 自定义模板
- savedInstanceState
- Ubuntu 下 网易云音乐使用体验
- 解决nagios报错:./stdio.h:456:1: error: 'gets' undeclared here (not in a function)的问题
- 二、谈谈算法
- JavaScript性能优化技巧之函数节流
- 写开源项目步骤(上传github、发布到jcenter、录屏gif)
- c与sv混合仿真的简单示例
- 单口RAM、双口RAM、FIFO
- adaboost xgboost gbdt 三个boosting方法整理
- OSG+VS2013+Win7 环境搭建
- iOS统计xcode代码行数
- 长期运行kibana
- EL表达式概述