浅谈JavaScript函数节流

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

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

 function throttle ( method , context ){
        clearTimeout ( method.tId );
        method.tId = setTimeout ( function () {
           method.call ( context );
         } , 100);
     }

应用举例:
     假设有一个<div/>元素需要保持它的高度始终等同于宽度,可作如下编码:

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

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

下面是其他网友的补充

今天主要写写我们平时工作中需要的函数节流。可能有的朋友对函数节流没有意识。其实,在工作中,很多场景都需要我们进行js的节流。最常见的是屏幕伸缩resize,以及touchmove或者scroll等事件的时候。大家不知道有没有看我之前写的文章!jquery判断页面滚动条上滚下滚,touchmove的滑动方向,大家在使用这些例子的时候,会发现页面不停的触发touchmove或者scroll因为这里没有关系到页面的重绘,因此,我在这里没有使用javascript函数节流。但是,当我们使用window.onresize的时候,也会不停的触发resize事件!这里就会关系到页面的重新绘制问题了。因此,在window的resize的时候,我们推荐大家使用函数节流的方式!

javascript函数节流简介
假如你对我上面一大坨文字感到头大,没关系,我在这里简单举例说明一下函数节流吧!例如当我们使用

 $(window).resize(function(){
      console.log("haorooms window resize");
    })

会发现:

这里会输出好多次。我们简单的缩小一下窗口,就会不停的触发!

这样在div很多的时候,页面不停重绘,要是遇到版本比较低的IE等,很可能会出现浏览器崩溃的现象!为了避免这种情况,我们可以用函数节流的方式。基本的思想是:第一次调用函数的时候,我们创建一个定时器,在指定时间间隔之后运行代码,第二次调用的时候,会清楚前一个定时器,并重新设置一个。如果前一个定时器已经执行过了,那么这个操作就没有有意了,如果定时器尚未执行,就会将其替换为一个新的定时器。目的是在执行函数停止了一段时间之后再执行。

用对象的方式可以如下写:

var haoroomstest={
      timeoutId:null,
      performProcessing:function(){
          console.log("resize");      

      },
      process:function(){
        clearTimeout(this.timeoutId);
        var that=this;
        this.timeoutId=setTimeout(function(){
          that.performProcessing();
        },500)
      }
    }

这样之后,我们再用:

$(window).resize(function(){ haoroomstest.process(); })

这样就会减少请求,减少dom重绘,达到节流的目的!

函数节流其他方式
除了我们运用对象的方式,网上及资料中也介绍了关于函数节流的其他方法和方式,我下面简单介绍几种!

函数方式一

function throttle(method,context){
      clearTimeout(method.tId);
      method.tId=setTimeout(function(){
        method.call(context);
      },100);
    }

我们如下使用

function resizeDIv(){
      console.log("haorooms")
    }

    $(window).resize(function(){
      throttle(resizeDIv)
    })

和上面对象实现了同样的效果!

函数方式二

网上还有一种比较流行的节流方式,我在这里写一下!

function throttle(method,delay){
      var timer=null;
      return function(){
        var context=this, args=arguments;
        clearTimeout(timer);
        timer=setTimeout(function(){
          method.apply(context,args);
        },delay);
      }
    }

然后可以这么写:

function resizeDIv(){
      console.log("haorooms")
    }

   window.onresize=throttle(resizeDIv,500);

新需求

我们在做模糊搜索智能联想提示的时候,会在input上面绑定keyup事件。但是我又不想触发的那么频繁,用上面的方式就会有问题。因此,在上面的函数基础上稍加改动,如下:

function throttle(method,delay,duration){
      var timer=null, begin=new Date();
      return function(){
        var context=this, args=arguments, current=new Date();;
        clearTimeout(timer);
        if(current-begin>=duration){
           method.apply(context,args);
           begin=current;
        }else{
          timer=setTimeout(function(){
            method.apply(context,args);
          },delay);
        }
      }
}

这样触发就不会有之前那么频繁了!

时间: 2014-12-07

JavaScript 函数节流详解及方法总结

JavaScript 函数节流详解 浏览器一个网页的UI线程只有一个,他同时会处理界面的渲染和页面JavaScript代码的执行(简单扩展一下,浏览器或者JavaScript运行大环境并不是单线程,诸如ajax异步回调.hybrid框架内与native通信.事件队列.CSS运行线程等等都属于多线程环境,不过ES6引入了Promise类来减少了部分异步情况).因此当JavaScript代码运行计算量很大的方法时,就有可能阻塞UI线程,小则导致用户响应卡顿,严重的情况下浏览器会提示页面无响应是否强制

JavaScript触发onScroll事件的函数节流详解

问题描述 常见的网站布局,顶部一个导航栏,我们假设本页面共有四个栏目:分别为A.B.C.D,我们点击A,锚点跳转至A栏目,同时顶部的A按钮高亮:点击B,锚点跳转至B栏目,同时顶部的B按钮高亮:我们在Main组件里面滚动,滚动到B模块时,B按钮高亮.以上是我们经常会在开发中遇到的一个模型.如果是在以前,用jQuery作前端开发的话,实在是太熟悉不过了. 解决方案 主要想谈谈在React组件化开发中的性能优化方法. 我们的页面结构是这样的 <div className={style.main} id

JS中setTimeout的巧妙用法前端函数节流

什么是函数节流? 函数节流简单的来说就是不想让该函数在很短的时间内连续被调用,比如我们最常见的是窗口缩放的时候,经常会执行一些其他的操作函数,比如发一个ajax请求等等事情,那么这时候窗口缩放的时候,有可能连续发多个请求,这并不是我们想要的,或者是说我们常见的鼠标移入移出tab切换效果,有时候连续且移动的很快的时候,会有闪烁的效果,这时候我们就可以使用函数节流来操作.大家都知道,DOM的操作会很消耗或影响性能的,如果是说在窗口缩放的时候,为元素绑定大量的dom操作的话,会引发大量的连续计算,比如

JavaScript函数节流和函数防抖之间的区别

一.概念解释 函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段. 大家大概都知道旧款电视机的工作原理,就是一行行得扫描出色彩到屏幕上,然后组成一张张图片.由于肉眼只能分辨出一定频率的变化,当高频率的扫描,人类是感觉不出来的.反而形成一种视觉效果,就是一张图.就像高速旋转的风扇,你看不到扇叶,只看到了一个圆一样. 同理,可以类推到js代码.在一定时间内,代码执行的次数不一定要非常多.达到一定频率就足够了.因为跑得越多,带来的效果也是一样.倒不如,把js代码的执行次数控制在合理的范围.既

JavaScript函数节流的两种写法

最近看了函数节流的相关内容,具体什么是节流我不讨论了,网上很多,这里总结下两个方法,我只认可其中一个.另一个貌似也能达到节流的效果但是感觉不是很正规. 方法一: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>函数节流</title> <style> div{ font-size:40px;

JavaScript函数节流概念与用法实例详解

本文实例讲述了JavaScript函数节流概念与用法.分享给大家供大家参考,具体如下: 最近在做网页的时候有个需求,就是浏览器窗口改变的时候需要改一些页面元素大小,于是乎很自然的想到了window的resize事件,于是乎我是这么写的 <!DOCTYPE html> <html> <head> <title>Throttle</title> </head> <body> <script type="text

JavaScript性能优化之函数节流(throttle)与函数去抖(debounce)

函数节流,简单地讲,就是让一个函数无法在很短的时间间隔内连续调用,只有当上一次函数执行后过了你规定的时间间隔,才能进行下一次该函数的调用. 函数节流的原理挺简单的,估计大家都想到了,那就是定时器.当我触发一个时间时,先setTimout让这个事件延迟一会再执行,如果在这个时间间隔内又触发了事件,那我们就clear掉原来的定时器,再setTimeout一个新的定时器延迟一会执行,就这样. 以下场景往往由于事件频繁被触发,因而频繁执行DOM操作.资源加载等重行为,导致UI停顿甚至浏览器崩溃. 1.

javascript性能优化之事件委托实例详解

本文实例分析了javascript性能优化之事件委托.分享给大家供大家参考,具体如下: 为下面每个LI绑定一个click事件 <ul id="myLinks"> <li id="goSomewhere" >Go somewhere</li> <li id="doSomething" >Do something</li> <li id="sayHi" >Sa

JavaScript性能优化总结之加载与执行

前言 无论当前 JavaScript 代码是内嵌还是在外链文件中,页面的下载和渲染都必须停下来等待脚本执行完成.JavaScript 执行过程耗时越久,浏览器等待响应用户输入的时间就越长.浏览器在下载和执行脚本时出现阻塞的原因在于,脚本可能会改变页面或 JavaScript 的命名空间,它们对后面页面内容造成影响.一个典型的例子就是在页面中使用document.write(),例如清单 1 清单 1 JavaScript 代码内嵌示例 <html> <head> <title

基于JavaScript 性能优化技巧心得(分享)

JavaScript 作为当前最为常见的直译式脚本语言,已经广泛应用于 Web 应用开发中.为了提高Web应用的性能,从 JavaScript 的性能优化方向入手,会是一个很好的选择. 本文从加载.上下文.解析.编译.执行和捆绑等多个方面来讲解 JavaScript 的性能优化技巧,以便让更多的前端开发人员掌握这方面知识. 什么是高性能的 JavaScript 代码? 尽管目前没有高性能代码的绝对定义,但却存在一个以用户为中心的性能模型,可以用作参考:RAIL模型. 响应 如果你的应用程序能在1

JavaScript 性能优化小结

随着 Web2.0 技术的不断推广,越来越多的应用使用 JavaScript 技术在客户端进行处理,从而使 JavaScript 在浏览器中的性能成为开发者所面临的最重要的可用性问题.而这个问题又因 JavaScript 的阻塞特性变的复杂,也就是说当浏览器在执行 JavaScript 代码时,不能同时做其他任何事情.本文详细介绍了如何正确的加载和执行 JavaScript 代码,从而提高其在浏览器中的性能. 在J2EE编程中,我们接触最多的脚本语言还是JavaScript.在使用JavaScr

javascript性能优化之DOM交互操作实例分析

本文实例讲述了javascript性能优化之DOM交互操作技巧.分享给大家供大家参考,具体如下: 在javascript各个方面,DOM毫无疑问是最慢的一部分.DOM操作与交互要耗费大量时间,因为它们往往需要重新渲染整个页面或者某一部分.理解如何优化与DOM的交互可以极大提高脚本完成的速度. 1.最小化DOM更新 看下面例子: var list = document.getElementById("ul"); for (var i=0; i < 10; i++){ var ite

javascript性能优化之分时函数的介绍

分时函数和函数节流的问题不一样,函数节流针对的事件不是用户主动调用的,前面已经提过了. 函数节流的原理是:延迟当前函数的执行,如果该次延迟还没有完成,那么忽略接下来该函数的请求.也就是说会忽略掉很多函数请求. 在一些开发场景中,我们可能会一次性向文档中注入上千个节点,在短时间内向浏览器中大量添加DOM节点可能会让浏览器吃不消,结果往往会让浏览器卡顿或吃不消,解决方案之一便是使用分时函数(timeChunk). timeChunk分时函数让创建节点的工作分批进行,比如一秒钟创建1000个节点,改为

JavaScript性能优化 创建文档碎片(document.createDocumentFragment)

在浏览器中,我们一旦把节点添加到document.body(或者其他节点)中,页面就会更新并反映出这个变化,对于少量的更新,一条条循环插入也会运行很好,也是我们常用的方法.代码如下: 复制代码 代码如下: for(var i=0;i<5;i++){ var op = document.createElement("span"); var oText = document.createTextNode(i); op.appendChild(oText); document.body

JavaScript性能优化之小知识总结

随着网络的发展,网速和机器速度的提高,越来越多的网站用到了丰富客户端技术.而现在Ajax则是最为流行的一种方式.JavaScript是一种解释型语言,所以能无法达到和C/Java之类的水平,限制了它能在客户端所做的事情,为了能改进他的性能,我想基于我以前给JavaScript做过的很多测试来谈谈自己的经验,希望能帮助大家改进自己的JavaScript脚本性能. 前言 一直在学习javascript,也有看过<犀利开发Jquery内核详解与实践>,对这本书的评价只有两个字犀利,可能是对javas