Timer waren schon immer die Kerntechnologie der JavaScript-Animation. Der Schlüssel zum Schreiben einer Animationsschleife besteht darin, zu wissen, wie lang die Verzögerungszeit ist. Einerseits muss das Schleifenintervall kurz genug sein, damit verschiedene Animationseffekte flüssig erscheinen; andererseits muss das Schleifenintervall lang genug sein, um sicherzustellen, dass der Browser die resultierenden Änderungen rendern kann.
Die Bildwiederholfrequenz der meisten Computermonitore beträgt 60 Hz, was ungefähr 60 Neuzeichnungen pro Sekunde entspricht. Die meisten Browser beschränken die Neuzeichnungsvorgänge auf maximal die Neuzeichnungshäufigkeit des Displays, da die Benutzererfahrung auch über diese Häufigkeit hinaus nicht verbessert wird. Daher beträgt das optimale Schleifenintervall für die reibungsloseste Animation 1000 ms/60, was ungefähr 16,6 ms entspricht.
Das Problem mit setTimeout und setInterval besteht darin, dass sie nicht präzise sind. Ihr interner Betriebsmechanismus bestimmt, dass der Zeitintervallparameter eigentlich nur die Zeit angibt, die der Animationscode zur Thread-Warteschlange der Browser-Benutzeroberfläche hinzugefügt wird, um auf die Ausführung zu warten. Wenn andere Aufgaben am Anfang der Warteschlange hinzugefügt wurden, muss der Animationscode warten, bis die vorherige Aufgabe abgeschlossen ist, bevor er sie ausführt.
requestAnimationFrame verwendet das Systemzeitintervall, um die beste Zeicheneffizienz aufrechtzuerhalten. Es führt nicht zu einer Überzeichnung und einem erhöhten Overhead, weil das Intervall zu lang ist Verschiedene Animationseffekte für Webseiten können erzielt werden. Es gibt einen einheitlichen Aktualisierungsmechanismus, um Systemressourcen zu sparen, die Systemleistung zu verbessern und visuelle Effekte zu verbessern.
MerkmaleDie requestAnimationFrame-Methode verwendet einen Rückruf als Parameter, und die Rückruffunktion wird in einem Parameter, DOMHighResTimeStamp, übergeben, der den Zeitpunkt angibt, zu dem die aktuell nach requestAnimationFrame() sortierte Rückruffunktion ausgelöst wird. Der Rückgabewert ist eine Anforderungs-ID, die eine eindeutige Kennung in der Rückrufliste darstellt. Dieser Wert kann an window.cancelAnimationFrame() übergeben werden, um die Rückruffunktion abzubrechen.
requestID = window.requestAnimationFrame(callback);
Mithilfe dieser API können bestimmte Codes beim nächsten erneuten Rendern ausgeführt werden, um zu vermeiden, dass in kurzer Zeit eine große Anzahl von Reflows ausgelöst wird.
Beispielsweise eignet sich die Rückruffunktion des Seiten-Scroll-Ereignisses (Scroll) sehr gut für die Verwendung dieser API und verschiebt den Rückrufvorgang bis zum nächsten erneuten Rendern. Es ist jedoch zu beachten, dass requestAnimationFrame keine Rückruffunktionen verwaltet. Das heißt, wenn Sie requestAnimationFrame mehrmals mit derselben Rückruffunktion aufrufen, bevor der Rückruf ausgeführt wird, wird der Rückruf mehrmals im selben Frame ausgeführt. Der einfachste Weg besteht darin, dieses Problem mit einer Drosselungsfunktion zu lösen, oder Sie können eine Möglichkeit finden, nur eine einzige Rückruffunktion in der Warteschlange von requestAnimationFrame zu haben:
let ScheduledAnimationFrame = false;document.body.onscroll = () => { if (scheduledAnimationFrame) return; window.requestAnimationFrame(() => { ScheduledAnimationFrame = false; // etwas tun });};
Das beste Anwendungsszenario ist natürlich immer noch die Frame-Animation, die die Leistung erheblich optimieren kann.
Interviewfragen So rendern Sie Zehntausende Daten, ohne in der Benutzeroberfläche hängen zu bleibenIn dieser Frage wird untersucht, wie Daten gerendert werden, ohne die Seite zu blockieren. Das heißt, Sie können nicht Zehntausende von Elementen auf einmal rendern, sondern sollten einen Teil des DOM auf einmal rendern. Anschließend können Sie es alle 16 ms über requestAnimationFrame aktualisieren.
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <meta name=viewport content=width=device-width, initial-scale=1.0> <meta http-equiv=X-UA -Compatible content=ie=edge> <title>Document</title></head><body> <ul>Control</ul> <script> setTimeout(() => { // 100.000 Datenteile einfügen const total = 100000 // 20 Teile gleichzeitig einfügen, const einmal reduzieren = 20 // Wie oft wird es dauern, die Daten zu rendern? einmal let countOfRender = 0 let ul = document. querySelector(ul); function add() { // Leistung optimieren, Einfügung verursacht keinen Rückfluss const fragment = document.createDocumentFragment(); for (let i = 0; i < Once; i++) { const li = document.createElement(li); li.innerText = Math.floor(Math.random() * total); 1; loop(); } function loop() { if (countOfRender < loopCount) { window.requestAnimationFrame(add } } loop(); }, 0); </script></body></html>Kompatibilität
Einige alte Browser unterstützen diese API nicht. Um diese API zu verwenden, können Sie diese Methode anpassen und sie unter dem Fenster bereitstellen:
(function() { var lastTime = 0; var sellers = ['webkit', 'moz']; for(var x = 0; x < sellers.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] ||. window[vendors[x]+'CancelRequestAnimationFrame'] } if (!window.requestAnimationFrame) window.requestAnimationFrame = function(callback) { var currTime = new Date().getTime(); 0, 16 - (currTime - lastTime)); var id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall); lastTime = currTime + timeToCall;
Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er für das Studium aller hilfreich ist. Ich hoffe auch, dass jeder das VeVb Wulin Network unterstützt.