Vue source knowledge point-passive

Posted May 26, 20203 min read

Vue source knowledge point-passive

reference

Source code interception

var supportsPassive = false;
if(inBrowser) {
  try {
    var opts = {};
    Object.defineProperty(opts, 'passive',({
      get:function get() {
       /* istanbul ignore next * /
        supportsPassive = true;
      }
    })); //https://github.com/facebook/flow/issues/285
    window.addEventListener('test-passive', null, opts);
  } catch(e) {}
}

addEventListener

In the early MDN standard, the usage of addEventListener is like this

target.addEventListener(type, listener, useCapture);

But the latest standard has become like this

target.addEventListener(type, listener, options);

In other words, the third parameter has changed from useCapture(Boolean) to options(object), but not all browsers have supported the new standard

passive

target.addEventListener(type, listener, {
    capture:false, //Capture
    passive:false,
    once:false //only trigger once
})

passive:Boolean, when set to true, it means that listener will never call preventDefault(). If the listener still calls this function, the client will ignore it and throw a console warning.

The role of passive

passive is mainly used to optimize the performance of browser page scrolling and make page scrolling smoother

  1. Scrolling is the default behavior of the browser, it can be prevented by preventDefault, such as

     window.addEventListener("mousewheel", function(e) {
       e.preventDefault()
     }, {
       passive:false
     });

    After adding the above code, the page will not scroll

  2. Since the browser cannot know in advance whether preventDefault() will be called in an event processing function, it needs to wait until the event processing function is executed before it can perform the default behavior. However, the execution of the event processing function takes time, such a Will cause the page to freeze

  3. We can explicitly tell the browser by passing passive as true, the event handler will not call preventDefault to prevent the default sliding behavior, and the browser will not wait for the event handler function to complete before performing the scroll, even if the scroll event writes a dead Loop, the browser can also handle the sliding of the page normally

Vue source code analysis cited at the beginning of the article

Looking back at the vue source code cited at the beginning of the article, in fact, the function of this code is polyfill, which is used to check whether the browser supports passive. As introduced in the addEventListener section, not all browsers support the setting of passive.

var supportsPassive = false;
if(inBrowser) {
  try {
    var opts = {};
    Object.defineProperty(opts, 'passive',({
      get:function get() {
       /* istanbul ignore next * /
        supportsPassive = true;
      }
    })); //https://github.com/facebook/flow/issues/285
    window.addEventListener('test-passive', null, opts);
  } catch(e) {}
}

window.addEventListener('test-passive', null, opts);

This line of code sets an empty event handler, the purpose is not to trigger the 'test-passive' event later, in fact, when this line of code is executed, the third parameter opts of addEventListener is an object, so that if the browser will third If a parameter is identified as an object and supports the setting of passive, the value of the passive option will be checked, that is, the browser will obtain the value of opts.passive, so that the get function will be called, and supportsPassive is set to true

If the browser does not support passive, then it will not get opts.passive, naturally supportsPassive remains false