Mussten Sie jemals Code im Browser ausführen, dessen Ausführung so lange dauerte, bis Ihre Anwendung für eine Weile nicht mehr reagierte? Mit HTML5-Webworkern müssen Sie das nie wieder erleben.
Mit Web Workern können Sie Code mit langer Laufzeit trennen und unabhängig von anderem Code ausführen, der auf der Seite ausgeführt wird. Dadurch bleibt Ihre Benutzeroberfläche auch bei komplexen Vorgängen reaktionsfähig.
Was sind Webworker?
Traditionell ist JavaScript eine Singlethread-Sprache. Das bedeutet, dass nichts anderes ausgeführt werden kann, während ein Codeabschnitt ausgeführt wird. Wenn Sie beispielsweise Code haben, der versucht, ein DOM-Element zu animieren, muss der Code, der versucht, eine Variable zu ändern, warten, bis die Animation beendet ist, bevor sie ausgeführt werden kann.
Web Worker sind JavaScript-Dateien, die in einem separaten Thread ohne direkten Zugriff auf das DOM ausgeführt werden.
Man kann sich Webworker so vorstellen, dass es sich um Codeteile handelt, deren Ausführung viel Zeit in Anspruch nimmt, sodass Sie sie dem Browser zur Ausführung im Hintergrund übergeben. Da dieser Code nun im Hintergrund läuft, hat er keinen Einfluss auf das für Ihre Webseite zuständige JavaScript.
Als Nebeneffekt kann es nicht mehr direkt mit dem Rest Ihres Codes interagieren, sodass Webworker keinen Zugriff auf das DOM haben. Viele andere Browser-APIs sind jedoch weiterhin verfügbar, einschließlich der WebSocket- und Fetch-APIs.
Web-Worker sind jedoch nicht vollständig vom Haupt-Thread isoliert. Wenn ein Worker mit dem Haupt-Thread kommunizieren muss, kann er eine Nachricht senden, und der Haupt-Thread kann als Antwort seine eigene Nachricht senden.
Warum Webworker?
Vor Webworkern war die einzige Möglichkeit, JavaScript auszuführen, die viel Zeit im Browser erforderte, entweder:
- Akzeptieren Sie, dass die Seite für eine Weile nicht reagiert.
- Brechen Sie diesen Code in asynchrone Stücke.
Da eine nicht reagierende Seite normalerweise eine schlechte Benutzererfahrung ist, können Sie sich für die asynchrone Option entscheiden. Code auf diese Weise zu schreiben bedeutet, ihn in kleinere Teile zu unterteilen, die der Browser ausführen kann, während er nicht die Benutzeroberfläche bearbeitet. Die Teile müssen klein genug sein, damit der Browser, wenn die Benutzeroberfläche aktualisiert werden muss, die Ausführung des aktuellen Teils abschließen und sich um die Benutzeroberfläche kümmern kann.
Webworker wurden zu HTML5 hinzugefügt, um eine bessere Lösung für dieses Problem anzubieten. Anstatt Sie zu zwingen, mit asynchronem Code kreativ zu werden, können Sie eine Funktion sauber trennen, um sie in einem eigenen isolierten Thread auszuführen.
Dies erleichterte es Entwicklern, solchen Code zu schreiben, und verbesserte auch die Benutzererfahrung.
Anwendungsfälle für Web-Worker
Jede Anwendung, die viel Rechenleistung auf der Client-Seite erfordert, könnte von Web Workern profitieren.
Angenommen, Ihre Anwendung möchte einen Nutzungsbericht erstellen und speichert aus Datenschutzgründen alle Daten auf dem Client.
Um diesen Bericht zu erstellen, muss Ihre Webanwendung die Daten abrufen, Berechnungen darauf ausführen, die Ergebnisse organisieren und sie dem Benutzer präsentieren.
Wenn Sie dies im Hauptthread versuchen würden, wäre der Benutzer vollständig unfähig, die Anwendung zu verwenden, während die Anwendung die Daten verarbeitet. Stattdessen können Sie diesen Code ganz oder teilweise in einen Webworker verschieben. Dadurch kann der Benutzer die Anwendung weiter verwenden, während die Berechnungen durchgeführt werden.
So verwenden Sie Web Worker in JavaScript
Das Web Worker-API definiert, wie Webworker verwendet werden. Die Verwendung dieser API beinhaltet die Erstellung eines Worker-Objekts mit dem Worker-Konstruktor wie folgt:
let newWorker = Worker('worker.js');
Das Arbeiter Der Konstruktor akzeptiert den Namen einer JavaScript-Datei als Parameter und führt die Datei in einem neuen Thread aus. Es gibt ein Worker-Objekt zurück, damit der Haupt-Thread mit dem Worker-Thread interagieren kann.
Worker interagieren mit dem Haupt-Thread, indem sie Nachrichten hin und her senden. Sie verwenden die POST-Meldung Funktion zum Senden von Ereignissen zwischen dem Worker und dem Haupt-Thread. Verwenden Sie die eine Nachricht Ereignis-Listener zum Abhören von Nachrichten von der anderen Partei.
Hier ist ein Codebeispiel. Zunächst könnte ein Hauptthread so aussehen:
Lassen Arbeiter = Neu Arbeiter('worker.js')
worker.postMessage('Hey!')
worker.onmessage = Funktion(e) {
Konsole.log ('Worker-Thread sagt', E.Daten)
}
Dieser Haupt-Thread erstellt ein Worker-Objekt aus worker.js und sendet ihm dann eine Nachricht mit worker.postMessage. Anschließend definiert es einen Ereignis-Listener, ähnlich dem Konzept von a DOM-Ereignis-Listener. Jedes Mal, wenn der Worker eine Nachricht an den Hauptthread zurücksendet, wird ein Ereignis ausgelöst, und der Handler protokolliert die Nachricht des Workers in der Konsole.
Der Code im Worker (worker.js) hat eine Aufgabe:
onmessage = Funktion(e) {
Lassen Nachricht = e.data;
Konsole.log ('Hauptthread gesagt', Botschaft);
POST-Meldung('Hi!')
}
Es wartet auf alle vom Haupt-Thread gesendeten Nachrichten, protokolliert die Nachricht in der Konsole und sendet eine Antwortnachricht zurück an den Haupt-Thread.
Die Nachrichten in diesem Beispiel waren alle Strings, aber das ist keine Voraussetzung: Sie können fast jeden Datentyp als Nachricht senden.
Die Art von Arbeitern, die Sie bisher gesehen haben, werden engagierte Arbeiter genannt. Sie können nur von der Datei aus darauf zugreifen, in der Sie sie erstellt haben (sie sind dafür vorgesehen). Shared Worker sind das Gegenteil: Sie können Nachrichten von mehreren Dateien empfangen und Nachrichten an mehrere Dateien senden. Shared Worker sind konzeptionell dasselbe wie Dedicated Worker, aber Sie müssen sie etwas anders verwenden.
Schauen wir uns ein Beispiel an. Anstatt den Worker-Konstruktor zu verwenden, muss jede Datei, die einen gemeinsam genutzten Worker verwenden möchte, ein Worker-Objekt mit erstellen SharedWorker():
Lassen SharedWorker = Neu SharedWorker('worker.js')
Die Unterschiede hören hier jedoch nicht auf. Damit eine Datei eine Nachricht von einem gemeinsam genutzten Worker senden oder empfangen kann, muss sie dies tun, indem sie auf a zugreift Hafen Objekt, anstatt dies direkt zu tun. So sieht das aus:
sharedWorker.port.postMessage('Hi!')
sharedWorker.port.onMessage = Funktion(e) {
Konsole.log ('Der gemeinsam genutzte Worker hat gesendet', E.Daten);
}
Sie müssen das Port-Objekt auch innerhalb des Workers verwenden:
onconnect = Funktion(e) {
konst port = e.ports[0];
port.onmessage = Funktion(e) {
Konsole.log ('Nachricht erhalten', E.Daten)
port.postMessage('Hallo!');
}
}
Das onconnect Listener wird jedes Mal ausgelöst, wenn eine Verbindung zu einem Port hergestellt wird (wenn eine eine Nachricht Ereignis-Listener wird im Haupt-Thread eingerichtet).
Wenn das passiert, ruft der Code den Port, mit dem gerade verbunden wurde, aus dem Connect-Ereignis ab und speichert ihn in einer Variablen. Als nächstes registriert der Code die eine Nachricht Listener für das Port-Objekt. Der Code protokolliert dann die Nachricht in der Konsole und verwendet den Port, um eine Nachricht zurück an den Haupt-Thread zu senden.
Web Worker verbessern die Benutzererfahrung
Web Worker sind JavaScript-Threads, mit denen Sie komplexe und lang andauernde Codeteile im Hintergrund ausführen können. Dieser Code verhindert dann, dass die Benutzeroberfläche blockiert wird. Die Verwendung von Web Workern macht das Schreiben dieser Art von Code viel einfacher und verbessert die Erfahrung für den Benutzer der Anwendung. Mithilfe der Web-Worker-API können Sie Web-Worker erstellen und mit ihnen interagieren.