使用passive优化性能

addEventListener可以传递第三个参数{passive: true},它表示 listener 永远不会调用 preventDefault()。如果 listener 仍然调用了这个函数,客户端将会忽略它并抛出一个控制台警告。

这是什么意思呢?比如,在移动端监听touchstart事件来获取手指第一次接触屏幕,如果添加了event.preventDefault(),浏览器应该阻止默认行为,但是,如果没添加event.preventDefault()的话,浏览器应该不拦截touch相关操作。但是浏览器提前是无法预知是否添加过event.preventDefault()的,所以浏览器会先执行以下touchstart之中的代码,比如在200ms后,它知道里面添加了还是没添加event.preventDefault(),这时候,浏览器才知道该怎么做。

那么,如果我们确定在touchstart中不会调用preventDefault(),那么,我们可以为其添加第三个参数{passive: true},来事先告诉浏览器,略过浏览器预先执行的这部分性能消耗,从而优化性能。

addEventListener('touchstart', handleTouchStart, { passive: true });

但是,{passive: true}并不是所有的浏览器都支持。

浏览器支持度

对于不支持的浏览器,我们只能传递truefalse。不过,已经有人做了很好的polyfill。

// Test via a getter in the options object to see 
// if the passive property is accessed
var supportsPassive = false;
try {
  var opts = Object.defineProperty({}, 'passive', {
    get: function() {
      supportsPassive = true;
    }
  });
  window.addEventListener("test", null, opts);
} catch (e) {}

// Use our detect's results. 
// passive applied if supported, capture will be false either way.
elem.addEventListener(
  'touchstart',
  fn,
  supportsPassive ? { passive: true } : false
); 

这段代码写得比较巧妙,完美的检测了浏览器的支持情况。

如果您觉得本文对您有用,欢迎捐赠或留言~
微信支付
支付宝

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注