js 性能优化整理之 高频优化

mousemove 拖拽操作

var count = 0;
elem.onmousemove = function(){
    count++;
    // 当计数器为偶数的时候不执行mousemove
    if( count % 2 === 0 ){
    return;
    }

    // 实现拖拽功能的代码...
};

 

高频事件的简单处理

var throldHold = 200; //两次scroll事件触发之间最小的事件间隔
window.onscroll = function () {
    if (arguments.callee.timer) {
        clearTimeout(arguments.callee.timer);
    }
    arguments.callee.timer = setTimeout(isDivScroll, throldHold);
}
//isDivScroll滚动执行的方法

 


 

mousewheel 滚轮操作

window.onmousewheel = throttle(function(){
    // 滚轮滚动时的操作代码..
}, 200 );

 

 

resize  窗口操作  ie每次比其他浏览是多重复触发一次

window.onresize = throttle(function(){  //普通绑定
    // 自适应布局的代码...
}, 200 );


window.addEventListener("resize", throttle(function(){  //监听绑定
		console.log('重置');
},200),false);

 

 

 

// 立即执行版
function debounce(func, wait) {
    let timer;
    return function() {
      let context = this; // 这边的 this 指向谁?
      let args = arguments; // arguments中存着e
 
      if (timer) clearTimeout(timer);
 
      let callNow = !timer;
 
      timer = setTimeout(() => {
        timer = null;
      }, wait)
 
      if (callNow) func.apply(context, args);
    }
}

  阿萨

// 合成版
/**
   * @desc 函数防抖
   * @param func 目标函数
   * @param wait 延迟执行毫秒数
   * @param immediate true - 立即执行, false - 延迟执行
   */
function debounce(func, wait, immediate) {
    let timer;
    return function() {
      let context = this,
          args = arguments;
           
      if (timer) clearTimeout(timer);
      if (immediate) {
        let callNow = !timer;
        timer = setTimeout(() => {
          timer = null;
        }, wait);
        if (callNow) func.apply(context, args);
      } else {
        timer  = setTimeout(() => {
          func.apply(context, args);
        }, wait)
      }
    }
}

  

参考别的框架的代码  UnderscoreJS 框架

function debounce(func, wait, immediate) {

 var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
  }
 
// 添加resize的回调函数,但是只允许它每300毫秒执行一次
window.addEventListener('resize', debounce(function(event) {
    // 这里写resize过程 
},300));

  

其他的

hadleClickthrottle(function(text,record,index){ },1000)

 

const throttle = (fn, wait = 800) => {
  // 上一次执行 fn 的时间
  var previous = 0
  // 将 throttle 处理结果当作函数返回
  return function(...args) {
    // 获取当前时间,转换成时间戳,单位毫秒
    let now = +new Date()
    // 将当前时间和上一次执行函数的时间进行对比
    // 大于等待时间就把 previous 设置为当前时间并执行函数 fn
    if (now - previous > wait) {
      previous = now
      fn.apply(this, args)
    }
  }
}

  ----------------------

 function debounce(func, wait, immediate) {
    var timeout, args, context, timestamp, result;
    return function() {
      context = this;
      args = arguments;
      timestamp = new Date();
      var later = function() {
        var last = (new Date()) - timestamp;
        if (last < wait) {
          timeout = setTimeout(later, wait - last);
        } else {
          timeout = null;
          if (!immediate) result = func.apply(context, args);
        }
      };
      var callNow = immediate && !timeout;
      if (!timeout) {
        timeout = setTimeout(later, wait);
      }
      if (callNow) result = func.apply(context, args);
      return result;
    };
  };

 

来自elementui

function debounce(fn) {
    var pending;
    return function () {
      if (!pending) {
        pending = new Promise(function (resolve) {
          Promise.resolve().then(function () {
            pending = undefined;
            resolve(fn());
          });
        });
      }

      return pending;
    };
  }

 使用如下

  // not necessary (debounced to run at most once-per-tick)
        update: debounce(function () {
          return new Promise(function (resolve) {
            instance.forceUpdate();
            resolve(state);
          });
        }),

  

 

 

 

------------------------------------------------------------------------------------

阻止mouseover和mouseout的反复触发

 function contains(parentNode, childNode) {
    if (parentNode.contains) {
        return parentNode != childNode && parentNode.contains(childNode);
    } else {
        return !!(parentNode.compareDocumentPosition(childNode) & 16);
    }
}
function checkHover(e,target){
    if (getEvent(e).type=="mouseover")  {
        return !contains(target,getEvent(e).relatedTarget||getEvent(e).fromElement) && !((getEvent(e).relatedTarget||getEvent(e).fromElement)===target);
    } else {
        return !contains(target,getEvent(e).relatedTarget||getEvent(e).toElement) && !((getEvent(e).relatedTarget||getEvent(e).toElement)===target);
    }
}

function getEvent(e){
    return e||window.event;
} 

document.getElementById("element").addEventListener("mouseover",function(e){
		  if(checkHover(e,this)){
	        console.log('鼠标进去一次');
	      }
	   },false);

  


posted @ 2015-05-12 14:19  surfaces  阅读(882)  评论(0编辑  收藏  举报