引子:昨天面试时面试官问了如何实现一个固定导航栏,在我答完后面试官问我可能存在哪些问题,如何优化?

这个问题我答得不太好,但现在回想起来应该有两个问题:

1. 把 fixbar元素 position:fixed 之后,它将脱离文档流,后面的元素将会跟上,这可能会形成一个闪烁,解决方法是跟随的元素设置 margin-top 为 fixbar 元素的高度,或者替换上一个等高的元素,这点面试时候没有描述出来。

2. 就是这篇博文主要内容 ”函数节流“,英文名 throttle 函数,在一些库,如underscore中有其实现,

主要思想是:对于非常频烦发射的事件,可以设置一定时间的”缓冲“,在这一定的时间内只执行最后一次时间的响应函数。

例如对于 窗口的滚动条拖动,onscroll时间是非常频繁发射的,如果每次发射都执行事件处理函数,那么将会增加浏览器负担,这时如果200ms(只是举例)执行一次,那么性能上将有所改善,效果上也能接受,当然实际应用需要二者找到一个平衡。

JQuery作者 John Resig 在2011年的一篇博文中提出了这个问题的最佳实践方法,请点击原文查看。代码如下:

    var outerPane = $details.find(".details-pane-outer"),
didScroll = false; $(window).scroll(function() {
didScroll = true;
}); setInterval(function() {
if ( didScroll ) {
didScroll = false;
// Check your page position and then
// Load in more results
}
}, 250);

通俗地大家把它称为 函数节流/事件稀释, 在 underscore 中,也有这个实现:

throttle_.throttle(function, wait, [options]) 
Creates
and returns a new, throttled version of the passed function, that, when
invoked repeatedly, will only actually call the original function at
most once per every waitmilliseconds. Useful for rate-limiting events that occur faster than you can keep up with.

By default, throttle will execute the function as soon as you call it for the first time, and, if you call it again any number of times during the wait period, as soon as that period is over. If you'd like to disable the leading-edge call, pass {leading: false}, and if you'd like to disable the execution on the trailing-edge, pass 
{trailing: false}.

var throttled = _.throttle(updatePosition, 100);
$(window).scroll(throttled);

以下是具体的实现代码:

 _.throttle = function(func, wait, options) {
var context, args, result;
var timeout = null;
var previous = 0;
if (!options) options = {};
var later = function() {
previous = options.leading === false ? 0 : _.now();
timeout = null;
result = func.apply(context, args);
if (!timeout) context = args = null;
};
return function() {
var now = _.now();
if (!previous && options.leading === false) previous = now;
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0 || remaining > wait) {
clearTimeout(timeout);
timeout = null;
previous = now;
result = func.apply(context, args);
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
return result;
};
};

参考链接:

Learning from Twitter

underscore.js

JavaScript 频繁发射事件处理的优化 --- 函数节流/事件稀释的更多相关文章

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

    函数节流,简单地讲,就是让一个函数无法在很短的时间间隔内连续调用,只有当上一次函数执行后过了你规定的时间间隔,才能进行下一次该函数的调用. 函数节流的原理挺简单的,估计大家都想到了,那就是定时器.当我 ...

  2. javascript 函数节流 throttle 解决函数被频繁调用、浏览器卡顿的问题

    * 使用setTimeout index.html <html> <head> <meta charset="UTF-8"> <title ...

  3. JavaScript性能优化技巧之函数节流

    函数节流技术的主要思路是,通过一个定时器,阻断连续重复的函数调用.对于我们自己内部使用的函数,这通常意义不大,也不推荐使用这个技术,它可能会丢失对某些数据的处理.但是对于在用户界面调用的函数,却非常有 ...

  4. 浅谈javascript函数节流

    浅谈javascript函数节流 什么是函数节流? 函数节流简单的来说就是不想让该函数在很短的时间内连续被调用,比如我们最常见的是窗口缩放的时候,经常会执行一些其他的操作函数,比如发一个ajax请求等 ...

  5. JavaScript函数节流与函数去抖

    介绍 首先解释一下这两个概念: 函数节流(throttle):是让一个函数无法在很短的时间间隔内连续调用,当上一次函数执行后过了规定的时间间隔,才能进行下一次该函数的调用. 函数去抖(debounce ...

  6. 浅谈javascript的函数节流

    什么是函数节流? 介绍前,先说下背景.在前端开发中,有时会为页面绑定resize事件,或者为一个页面元素绑定拖拽事件(其核心就是绑定mousemove),这种事件有一个特点,就是用户不必特地捣乱,他在 ...

  7. 深入理解javascript函数进阶系列第三篇——函数节流和函数防抖

    前面的话 javascript中的函数大多数情况下都是由用户主动调用触发的,除非是函数本身的实现不合理,否则一般不会遇到跟性能相关的问题.但在一些少数情况下,函数的触发不是由用户直接控制的.在这些场景 ...

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

    前言:针对一些会频繁触发的事件如scroll.resize,如果正常绑定事件处理函数的话,有可能在很短的时间内多次连续触发事件,十分影响性能 节流: 节流:使得一定时间内只触发一次函数. 它和防抖动最 ...

  9. javaScript函数节流与函数防抖

    javaScript函数节流与防抖之区别 函数防抖(debounce)与函数节流(throttle)都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟.假死或卡顿 ...

随机推荐

  1. unicode 编解码记录

    unicode 万国码.世界上所有的符号都有对应的Unicode code point.一般是2个字节. 这个字节可以通过任意中方式编码为二进制,例如用来保存到文件.一般通过UTF-x(例如utf-8 ...

  2. 微服务日志之Spring Boot Kafka实现日志收集

    前言 承接上文( 微服务日志之.NET Core使用NLog通过Kafka实现日志收集 https://www.cnblogs.com/maxzhang1985/p/9522017.html ).NE ...

  3. WPF学习笔记(6):DataSet更新后台数据库个别列失败的问题

    WPF窗体中建有一个DataGrid,运行后修改各行数据,通过Update方法更新后台数据库.发现在数据库中,其中一列FAcctID(文本型)每次都会变为0,还有一列FDebit(货币型)不能更新,其 ...

  4. 在ng-repeat内Checkbox默认选中

    Angularjs的ng-repeat是用来循环产生呈现数据. 当我们需要在ng-repeat循环中呈现一系列Checkbox时,某些checkbox选项是默认选中的. 在ASP.NET MVC程序中 ...

  5. 【BZOJ4025】 二分图(线段树分治)

    传送门 BZOJ Solution 只是为了学习一下线段树分治的啦! 当你学会线段树分治之后,可以跳过下面的一部分: 按照时间搞一颗线段树出来,把包含这段区间的操作用vector压进去. 每一个线段树 ...

  6. 微信小程序scroll-view 横向和纵向scroll-view组件

    scroll-view为滚动视图,分为水平滚动和垂直滚动.注意滚动视图垂直滚动时一定要设置高度否则的话scroll-view不会生效.滚动视图常用的地方一般都是Item项比较多的界面,比如我的模块 主 ...

  7. 微信小游戏 three.js jsonloader request:fail invalid url

    微信小游戏中,用 THREE.JSONLoader 直接加载本地的 json 文件,报错.估计是跨域访问的问题 解决:把 json 文件放到服务器上,通过 url 来访问. 临时测试的话,在本地起一个 ...

  8. mybatis 详解(一)

    http://www.cnblogs.com/ysocean/p/7271600.html 1.什么是MyBatis? MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目 ...

  9. [转]KMP算法理解及java实现

    这大概是我看的最好懂的KMP算法讲解了,不过我还只弄懂了大概思想,算法实现我到时候用java实现一遍 出处:知乎 https://www.zhihu.com/question/21923021/ans ...

  10. Jenkins 批量删除历史构建

    在一次巡查 Jenkins 时,发现很多个项目的历史构建比较多,这些历史构建对于现在来说又没有什么用处,那么想把它删除,但是一个一个删除很累,毕竟总共加起来有上千个,历史构建,而且还不只是一个项目.那 ...