DOM 上有些事件是会频繁触发的, 在做搜索的时候, 会出现这么一个问题, 一输入了一点点就需要去发送请求, 但是这样给服务器带来的压力是蛮大的, 可以尝试使用一下 lodash 中的. debounce 和. throttle.
debounce
防抖
img1
简单讲就是: 不管上游事件触发了多少次, 下游就产生了一次事件. 也就是说当一次事件发生后, 事件处理器要等一定阈值的时间, 如果这段时间过去后 再也没有 事件发生, 就处理最后一次发生的事件. 假设还差 0.01 秒就到达指定时间, 这时又来了一个事件, 那么之前的等待作废, 需要重新再等待指定时间.
这个就挺适合做搜索发起请求时候用的, 等到用户 keyup,keypress 之后隔了 xxms 之后, 没有下一个动作, 说明他已经完成了输入, 这时候, 可以进行请求的发送, 下面给一个最简单的例子来展示:
JS 部分:
- // 引入
- import debounce from 'lodash.debounce';
- // 设置函数去抖
- var debounceFn=debounce(function(){
- // 这里进行 你想做的操作 比如发请求 什么的
- var inputVal = $("#searchInput").val();
- self.searchcinemas(inputVal,city.code,{ "cityX": 121.47,"cityY": 31.23}, self.config.cinemaData,searchPageIndex,cityChange);
- },300);
- $('.schedules-block-container').find('header input').off().on('change input',function(){
- debounceFn();
- }).on('click', function() {
- this.focus();
- });
- throttle
节流
throttle 也就是不允许方法在每 xxx ms 间执行超过一次, throttle 和 debounce 的区别在于: throttle 可以保证方法每 xxx ms 有规律的执行.
一个相当常见的例子, 用户在你无限滚动的页面上向下拖动, 你需要判断现在距离页面底部多少. 如果用户快接近底部时, 我们应该发送请求来加载更多内容到页面.
在此 .debounce 没有用, 因为它只会在用户停止滚动时触发, 但我们需要用户快到达底部时去请求. 通过. throttle 我们可以不间断的监测距离底部多远.
requestAnimationFrame (rAF)
requestAnimationFrame 是另一个频率限制的方法. requestAnimationFrame 可以作为 throttle 的代替方法.
利:
目标 60fps(16ms 每贞), 但是内部使用最优的时间间隔来渲染
使用简单并且是标准 API, 以后不会变动, 不需要维护
弊:
rAF 的开始或者取消需要我们自己处理, 不像. debounce 和. throttle 内部实现
浏览器 Tag 没有激活, 它就不会执行
即使多数现代浏览器支持, 但是 IE9,Opera Mini 以及老版本 Android 依旧不支持. A polyfill 到现在依旧需要
rAF 在 node.JS 中不支持
建议在 JS 执行 "painting" 或 "animating" 中直接操作属性和重新计算元素位置时使用 rAF.
发送 Ajax 请求或者是否添加 / 删除 class(触发一个 CSS 动画)时, 我会考虑 debounce 和 throttle, 此时你可以降低执行频率(200ms 而不是 16ms).
总结
使用 debounce,throttle 和 requestAnimationFrame 优化你的事件处理函数. 每一个方法有一些细微的差别, 三个都很有用而且互相弥补.
debounce: 把突然涌进的事件 (键盘事件) 归为一个
throttle: 保证持续执行方法分隔为每 Xms 执行一次. 就像每 200ms 监测滚动位置来触发 CSS 动画.
requestAnimationFrame:throttle 的替代方案, 当你的方法需要重新计算和渲染元素同时你需要更平滑的变动或动画. 注意: IE9- 不支持.
来源: http://www.jianshu.com/p/facc3b51a418