javascript - Was sind passive Event-Listener?
Während ich daran gearbeitet habe, die Leistung für Progressive Web Apps zu steigern, bin ich auf eine neue Funktion Passive Event Listeners gestoßen und finde es schwer, das Konzept zu verstehen.
Was sind Passive Event Listeners und warum ist es notwendig, sie in unseren Projekten zu haben?
Antwort #1
Passive-Event-Listener sind ein aufkommender Webstandard, eine neue Funktion, die in Chrome 51 eingeführt wurde und eine bedeutende potenzielle Verbesserung der Scroll-Performance bietet. Chrome Release Notes.
Es ermöglicht Entwicklern, sich für eine bessere Scroll-Leistung zu entscheiden, indem die Notwendigkeit beseitigt wird, dass das Scrollen auf Touch- und Wheel-Ereignis-Listener blockiert.
Problem: Alle modernen Browser verfügen über eine Thread-basiertes Scrollen-Funktion, um ein flüssiges Scrollen zu ermöglichen, selbst wenn teures JavaScript ausgeführt wird, aber diese Optimierung wird teilweise durch die Notwendigkeit beeinträchtigt, auf die Ergebnisse von touchstart- und touchmove-Handlern zu warten, die das Scrollen vollständig verhindern können, indem sie preventDefault() auf das Ereignis aufrufen.
Lösung: {passiv: true}
Indem ein Touch- oder Wheel-Listener als passiv markiert wird, verspricht der Entwickler, dass der Handler preventDefault nicht aufruft, um das Scrollen zu deaktivieren. Dies ermöglicht es dem Browser, sofort auf das Scrollen zu reagieren, ohne auf JavaScript warten zu müssen, und sorgt so für ein zuverlässig reibungsloses Scroll-Erlebnis für den Benutzer.
document.addEventListener("touchstart", function(e) {
console.log(e.defaultPrevented); // will be false
e.preventDefault(); // does nothing since the listener is passive
console.log(e.defaultPrevented); // still false
}, Modernizr.passiveeventlisteners ? {passive: true} : false);
DOM-Spezifikation, Demo-Video, Erklärdokument
Antwort #2
tl;dr Wenn Sie e.preventDefault() im Ereignis nicht verwenden müssen, dann fügen Sie passive: true hinzu.
Das ist mein Verständnis davon.
Jedes Ereignis hat seine standardmäßige Ereignis-Verarbeitung.
Wir können addEventListener verwenden, um Ereignis-Listener für ein bestimmtes Ereignis hinzuzufügen. Innerhalb dieses hinzugefügten Ereignisses können wir preventDefault() verwenden, um die Ausführung des Standardereignisses zu verhindern.
Selbst wenn Sie preventDefault() verwenden, wird das Standardereignis tatsächlich trotzdem ausgeführt; es wird nur überprüft, ob Sie preventDefault() in seinen Voraktionen verwendet haben. Wenn ja, wird es nicht ausgeführt. Allerdings verursacht die Überprüfung von preventDefault() im Standardereignis erheblichen Mehraufwand.
Daher, wenn Sie passive: true innerhalb von addEventListener angeben können, wird es den Prozess erheblich beschleunigen, festzustellen, ob das Standardereignis ausgeführt werden soll. Es wird direkt als falsch behandelt, was bedeutet, dass das Standardereignis ausgeführt wird.
<script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/8.14.0/mermaid.min.js"></script>
<div class="mermaid">
flowchart TD
A[xxxEvent] --> B[default xxxEvent]
B-->C{check}
C --> |passive:false| E{preventDefault}
E --> |true|return
E --> |false|G[do default event]
C --> |passive:true| G[do default event]
</div>Daher ist das Setzen von passive: true eine bessere Wahl, wenn Sie preventDefault nicht verwenden müssen.
Sein Standardwert ist nicht wahr, um die Kompatibilität zu gewährleisten.
Wenn es auf true gesetzt wäre, wären ältere Programme, die preventDefault verwenden, im Wesentlichen gleichbedeutend damit, es überhaupt nicht zu setzen.
