频繁计算?
之前接到一个需求要把【导航/搜索过滤栏悬浮】改成用户上拉时不展示,下拉并达到一定距离时才展示出来,这类效果在各类APP中都有看到,其中需要计算用户下拉最终停下来时,共下拉了多少px,实现起来也不算太难,就不放代码了。
就是这频繁的打印(计算)引发了我的思考,这每秒都在算啊,对性能会不会...,一顿查资料后,发现js性能优化之防抖与节流。
普通情况
<div style="width: 100px;height: 2000px;background-color: skyblue;"></div>
window.onload = function(){
// 获取滚动条距顶高度
function getScrollTop() {
var scroll_top = 0;
if (document.documentElement && document.documentElement.scrollTop) {
scroll_top = document.documentElement.scrollTop;
}
else if (document.body) {
scroll_top = document.body.scrollTop;
}
return scroll_top;
}
/* 一、普通情况 */
window.addEventListener('scroll', function(){ console.log(getScrollTop()); });
/* end */
}
普通情况
js防抖
防抖是什么?防抖效果img
概念
当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。
即:连续触发事件,只执行一次。
例如上图所示,连续触发了滚动事件,但只有最后停下来了,且停下来的时间超过了1s,才执行打印。
/* 二、函数防抖 */
var timeout = null;
function debounce() {
if(timeout !== null){
clearTimeout(timeout); //清除这个定时器
}
timeout = setTimeout(function(){
console.log("防抖 ", getScrollTop());
}, 1000);
}
window.addEventListener('scroll', function(){
debounce();
});
/* 函数防抖 end */
所以,我文章开头的频繁计算问题,就可以通过防抖解决。
js节流
节流是什么?节流效果img
概念
当持续触发事件时,函数会以一定的频率触发。
例如上图所示,一直在触发滚动事件,但打印在以一定的时间间隔出现。
/* 三、函数节流 */
var timer = null;
var throttle = function() {
if (!timer) {
timer = setTimeout(function() {
console.log("节流 ", getScrollTop());
timer = null;
}, 1000);
}
}
window.addEventListener('scroll', function(){
throttle();
});
/* 函数节流 end */
其它场景
当项目中遇到有【高频事件触发】需求的时候,都可以想到节流与防抖。
比如做【搜索联想】时,可以用防抖来节约请求资源,而不是用户输一个字符就请求一次api。
再比如我在做【元素跟随鼠标】时,可以用节流来避免一直计算并设置元素坐标。
正常情况
加入节流后(每200ms设置一次坐标)