关闭

js前端性能优化之函数节流和函数防抖

时间: 2018-12-22阅读: 825标签: 优化

前言:

针对一些会频繁触发的事件如scroll、resize,如果正常绑定事件处理函数的话,有可能在很短的时间内多次连续触发事件,十分影响性能


节流:

节流:使得一定时间内只触发一次函数。 
它和防抖动最大的区别就是,节流函数不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而防抖动只是在最后一次事件后才触发一次函数。 
原理是通过判断是否到达一定时间来触发函数,若没到规定时间则使用计时器延后,而下一次事件则会重新设定计时器

主要有两种实现方法:

  • 时间戳
  • 定时器

时间戳实现:当高频事件触发时,第一次应该会立即执行(给事件绑定函数与真正触发事件的间隔如果大于delay的话),而后再怎么频繁触发事件,也都是会每delay秒才执行一次。而当最后一次事件触发完毕后,事件也不会再被执行了。

var throttle = function(func,delay){
    var prev = Date.now();
    return function(){
        var context = this;
        var args = arguments;
        var now = Date.now();
        if(now-prev>=delay){
            func.apply(context,args);
            prev = Date.now();
        }
    }
}

定时器实现: 当触发事件的时候,我们设置一个定时器,再触发事件的时候,如果定时器存在,就不执行;直到delay秒后,定时器执行执行函数,清空定时器,这样就可以设置下个定时器。

var throttle = fucntion(func,delay){
    var timer = null;

    return funtion(){
        var context = this;
        var args = arguments;
        if(!timer){
            timer = setTimeout(function(){
                func.apply(context,args);
                timer = null;
            },delay);
        }
    }
}

当第一次触发事件时,肯定不会立即执行函数,而是在delay秒后才执行。 
之后连续不断触发事件,也会每delay秒执行一次。 
当最后一次停止触发后,由于定时器的delay延迟,可能还会执行一次函数。

综合使用时间戳与定时器,完成一个事件触发时立即执行,触发完毕还能执行一次的节流函数:

var throttle = function(func,delay){
    var timer = null;
    var startTime = Date.now();

    return function(){
        var curTime = Date.now();
        var remaining = delay-(curTime-startTime);
        var context = this;
        var args = arguments;

        clearTimeout(timer);
        if(remaining<=0){
            func.apply(context,args);
            startTime = Date.now();
        }else{
            timer = setTimeout(func,remaining);
        }
    }
}


防抖动:

防抖动:将几次操作合并为一此操作进行。原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发

// 将会包装事件的 debounce 函数
function debounce(fn, delay) {
  // 维护一个 timer
  let timer = null;

  return function() {
    // 通过 ‘this’ 和 ‘arguments’ 获取函数的作用域和变量
    let context = this;
    let args = arguments;

    clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(context, args);
    }, delay);
  }
}


1. 首先,我们为scroll事件绑定处理函数,这时debounce函数会立即调用, 
 因此给scroll事件绑定的函数实际上是debounce内部返回的函数

2. 每一次事件被触发,都会清除当前的 timer 然后重新设置超时调用。 
    这就会导致每一次高频事件都会取消前一次的超时调用,导致事件处理程序不能被触发

3. 只有当高频事件停止,最后一次事件触发的超时调用才能在delay时间后执行

站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/1669

关闭

Webpack 打包后代码执行时机分析与优化

代码执行时机将决定着是否能够正常执行,当依赖文件没加载完成就开始执行、使用对应模块,那么将会导致执行异常。这在“ 存在资源加载失败时,加载重试影响原来文件的执行顺序 ”的场景下尤为常见。

从浏览器内部运行机制看性能优化

获取到的HTML/CSS/JS资源经过浏览器内核的处理生成图像呈现在浏览器上,那么下面我们就详细说说浏览器内核在拿到资源之后是经过哪些处理来生成我们最终所看到的页面。

我是如何将页面加载时间从6S降到2S的?

生活在信息爆炸的今天,我们每天不得不面对和过滤海量的信息--无疑是焦躁和浮动的,这就意味着用户对你站点投入的时间可能是及其吝啬的(当然有一些刚需站点除外)。如何给用户提供迅速的响应就显得十分重要了

网站性能优化实战

读取缓存→DNS查询→TCP链接→发起请求→接收响应→处理HTML元素→加载完成。CSS属性读写分离:浏览器每次对元素样式进行读操作时,都必须进行一次重新渲染(重排 + 重绘)

如何设置网站的robots.txt?

做过网站优化的朋友都知道,搜索引擎蜘蛛爬行抓取网站时首先会去访问根目录下的robots.txt文件,如果robots文件存在,则会根据robots文件内设置的规则进行爬行抓取,如果文件不存在则会顺着首页进行抓取,那么robots文件的工作原理是什么呢?

MySQL查询优化

MySQL的查询怎么才能更快,更合理?除了加索引还有什么可以学习的呢?要想更好地学习某样东西,从其原理和运作方式入手更容易掌握。

前端性能优化的三大处理方式

减少 HTTP 的请求次数和传输报文的大小,可以减少 HTTP 请求次数或者减少请求内容的大小 ,使图片渲染的更快:因为他们是基于代码渲染的,而对于位图(png/jpg/gif)是需要先把图片编码再渲染 ,可以避免图片失真变形

js节流阀和去抖动的基本实现

节流阀throttle:触发的事件以周期的形式去执行,而非实时。如滴水的水龙头。去抖动debounce:事件最后一次触发的N毫秒后触发,如电梯门。

工程架构的优化

client端和server端的配置有重复的地方,优化的手段就是将两个文件中重复的配置项提取出来,然后利用webpack-merge包去合并配置。提取公共的配置到webpack.config.base.js文件

js的防抖节流优化高频触发

js的防抖就是比如一个水龙头坏了一直在滴水,我们为了节约用水,那么我们会想办法让他不再滴的那么快,这就是防抖。常见的比如scroll,onresize这些高频触发的情况。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!