Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erläuterung der Drosselung der JavaScript-Funktion

Detaillierte Erläuterung der Drosselung der JavaScript-Funktion

黄舟
黄舟Original
2017-02-27 14:30:551405Durchsuche

Detaillierte Erläuterung der Drosselung der JavaScript-Funktion

Der Browser verfügt nur über einen UI-Thread für eine Webseite, der auch das Rendern der Schnittstelle und die Ausführung des JavaScript-Codes auf der Seite übernimmt (um es kurz zu erweitern). , die Browser- oder JavaScript-Ausführungsumgebung ist nicht Single-Threaded-Umgebung, wie z. B. asynchrone Ajax-Rückrufe, Ereigniswarteschlangen, CSS-Ausführungsthreads usw. Es handelt sich jedoch um Multithread-Umgebungen die Promise-Klasse, um einige asynchrone Situationen zu reduzieren). Wenn daher JavaScript-Code eine Methode ausführt, die viele Berechnungen erfordert, blockiert er möglicherweise den UI-Thread, was dazu führen kann, dass die Antwort des Benutzers einfriert. In schweren Fällen fragt der Browser, ob die Seite nicht reagiert und ob er dies erzwingen soll schließen. Zum Beispiel Seiten-Scroll-Ereignisse von Webseiten, Schiebe- und Zoom-Ereignisse von Mobilgeräten usw. Auch wenn keine ernsthaften Leistungsprobleme vorliegen, sollten wir aus Sicht der Leistungsoptimierung die umfangreiche Verarbeitungszeit entlasten, die in kurzer Zeit mehrmals ausgelöst wird.

Wie man effektiv verhindert, dass der UI-Thread zu langen Code ausführt, ist ein Problem, das alle Benutzerinteraktionsanwendungen berücksichtigen müssen. Für das gleiche Problem auf dem Client-Android können Sie den UI-Hauptthread verwenden, um Sub- zu öffnen. Threads, um Berechnungen zu verteilen. Dementsprechend kann js auch Berechnungen durch die Einführung von webWorker verteilen, aber es gibt eine einfachere und effektivere Methode in js: Funktionsdrosselung. Die Kerntechnik der Funktionsdrosselung besteht in der Verwendung von timersegmentierten Berechnungen. Es gibt grob zwei Ideen für spezifische Implementierungsmethoden.

·Methode 1

1. Die Idee dieser Implementierung ist leicht zu verstehen: Legen Sie ein Intervall fest, z. B. 50 Millisekunden, und stellen Sie den Timer basierend auf dieser Zeit ein Das erste Mal Wenn das Intervall zwischen dem Triggerereignis und dem zweiten Triggerereignis weniger als 50 Millisekunden beträgt, löschen Sie diesen Timer und stellen Sie einen neuen Timer ein usw., bis innerhalb von 50 Millisekunden nach Auslösung eines Ereignisses kein wiederholter Trigger erfolgt. Der Code lautet wie folgt:


function debounce(method){
   clearTimeout(method.timer);
   method.timer=setTimeout(function(){
      method();
   },50);
}

Bei diesem Design gibt es ein Problem: Ein Ereignis, das mehrmals ausgelöst werden sollte, kann am Ende nur einmal auftreten. Insbesondere bei einem allmählichen Bildlaufereignis: Wenn der Benutzer zu schnell scrollt oder das vom Programm festgelegte Funktionsdrosselungsintervall zu lang ist, erscheint das letzte Bildlaufereignis als plötzliches Sprungereignis und der Zwischenprozess wird durch Drosselung unterbrochen . . Dieses Beispiel ist etwas übertrieben, aber wenn Sie diese Methode zur Drosselung verwenden, werden Sie möglicherweise das Gefühl haben, dass das Programm „abrupter“ ist als wenn es nicht gedrosselt wird, was für die Benutzererfahrung sehr schlecht ist. Es gibt eine Designidee, um dieses Manko auszugleichen.


·Methode 2


2. Die Idee der zweiten Implementierungsmethode unterscheidet sich geringfügig von der ersten Erstens: Legen Sie eine Intervallzeit fest, z. B. 50 Millisekunden, um Ereignisauslöser basierend auf dieser Zeit stabil zu trennen. Das heißt, wenn mehrere Ereignisse innerhalb von 100 Millisekunden kontinuierlich ausgelöst werden, werden sie nur in einem stabilen Abstand von 50 Millisekunden ausgeführt. Der Code lautet wie folgt:


var oldTime=new Date().getTime();
var delay=50;
function throttle1(method){
   var curTime=new Date().getTime();
   if(curTime-oldTime>=delay){
      oldTime=curTime;
      method();
   }
}

Im Vergleich zur ersten Methode kann die zweite Methode häufiger ausgeführt werden als die erste Methode (manchmal bedeutet dies mehr) Mehrere Anfragen an der Hintergrund, d. h. mehr Verkehr), aber es behebt die Mängel der ersten Methode, um den Zwischenprozess zu löschen. Daher sollte in bestimmten Szenarien je nach Situation entschieden werden, welche Methode verwendet werden soll.


Für Methode zwei bieten wir eine andere Möglichkeit, dieselbe Funktion zu schreiben:

var timer=undefined,delay=50;
function throttle2(method){
    if(timer){
        return ;
    }
    method();
    timer=setTimeout(function(){
        timer=undefined;
    },delay);
}

Lassen Sie uns abschließend über die Funktionsdrosselung sprechen , werden Sie oft zwei Methodennamen sehen: Throttle und Debounce können mit „Control, Stuck“ übersetzt werden, und Debounce kann mit „Anti-Bounce“ übersetzt werden. In „JavaScript Advanced Programming“ führte der Autor die erste Methode ein und verwendete den Funktionsnamen „Throttle“. Im Buch „Third-Party JavaScript Programming“ werden sowohl Methode eins als auch Methode zwei genannt. Der Autor nennt Methode eins „Debounce“ und Methode zwei „Throttle“. Bei der gleichzeitigen Einführung zweier Methoden wird in einigen Artikeln in China Methode eins fälschlicherweise als „Throttle“ und Methode zwei als „Debounce“ bezeichnet, was aus englischer Sicht sehr unverantwortlich ist. Hier stellen wir die Dinge in Ordnung: Methode eins kann als „Anti-Bounce“ verstanden werden und sollte „Debounce“ genannt werden; Methode zwei kann als „Funktionsdrosselung“ verstanden werden und sollte „Throttle“ heißen.


Das Obige ist eine detaillierte Erklärung der JavaScript-Funktionsdrosselung. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn