Przejdź do zawartości

Web worker

Z Wikipedii, wolnej encyklopedii

Web worker (worker) – mechanizm platformy WWW dla aplikacji webowych umożliwiający uruchamianie skryptów (najczęściej w JavaScript) w tle, w odrębnym kontekście wykonania (zwykle w osobnym wątku), niezależnie od kodu działającego w głównym wątku strony (dokumentu HTML)[1][2]; oznacza wykonanie niezależnie, równolegle i równoczesne względem innych skryptów w tym samym dokumencie HTML(na tej samej stronie)[3].

Celem jest wykonywanie długotrwałych lub kosztownych obliczeniowo zadań bez „zatykania” interfejsu użytkownika (UI) i bez konieczności częstego oddawania sterowania w głównym wątku, co pomaga zachować responsywność aplikacji[2]. Komunikacja między stroną a workerem odbywa się przez wymianę komunikatów (np. postMessage) i zdarzenia message[2][4]. Web workery są w stanie wykorzystywać wielordzeniowe procesory[5].

Specyfikacja web workers jest utrzymywana w ramach HTML Standard (tzw. Living Standard) przez WHATWG[2]. W3C opublikowało równolegle notę dokumentującą API, lecz nie jest ona już głównym miejscem rozwoju tego standardu[6].

Stosowane są w celu poprawy responsywności aplikacji webowych: przeniesienie kosztownych obliczeń poza wątek główny zmniejsza ryzyko długich zadań (long tasks), które blokują interakcje użytkownika, i może poprawiać metryki wydajności związane z reakcją na wejście (np. INP)[1][4][7]. Do typowych zastosowań web workerów należą m.in.:

Web workery są też wykorzystywane jako „wątki wykonawcze” w scenariuszach wielowątkowego WebAssembly (tzw. WebAssembly threads). W takich zastosowaniach istotną rolę odgrywa SharedArrayBuffer (współdzielona pamięć), a dostęp do niego może wymagać stanu cross-origin isolated konfigurowanego nagłówkami COOP/COEP[10][11][12].

W praktyce wyróżnia się kilka typów workerów:

  • dedicated worker (worker, dedicated worker)— worker powołany przez skrypt strony jest dostępny tylko dla tego kontekstu (jednej karty/ramki/skryptu, który go utworzył); tworzony przez konstruktor Worker[1][2][13];
  • shared worker (shared worker) — jeden worker współdzielony przez wiele kontekstów przeglądania (np. kilka kart lub ramek) w obrębie tego samego origin; komunikacja odbywa się przez MessagePort[1][2];Powiązane technologie: service worker i worklety:
  • service worker (specyfikowany osobno) odrębny typ workera wykorzystywany m.in. do obsługi pracy w tle i scenariuszy offline (np. PWA, przechwytywania żądań, push i background sync); nie jest tym samym co klasyczne web workery uruchamiane z poziomu strony, choć dzieli z nimi ogólną ideę uruchamiania kodu poza głównym wątkiem[14][15];
  • worklets (również opisane w HTML Standard) służą do wyspecjalizowanych, lekkich zadań (np. audio/animacje) i nie są tym samym co klasyczne web workery[2].

Charakterystyka

[edytuj | edytuj kod]

Worker jest uruchamiany przez podanie adresu pliku skryptu (URL) w konstruktorze Worker. Kod workera wykonuje się w osobnym kontekście globalnym (zwykle odwołuje się do niego przez self); worker nie ma bezpośredniego dostępu do obiektu window ani DOM i nie może wprost modyfikować dokumentu HTML[4][7]. Komunikacja z interfejsem użytkownika (dokumentem HTML) odbywa się pośrednio: worker wysyła komunikaty do głównego wątku metodą postMessage(), a odbiera je w obsłudze zdarzenia message[1]. Dane przekazywane między wątkiem głównym a workerem są domyślnie kopiowane zgodnie z tzw. structured clone algorithm (serializacja/deserializacja), więc obie strony dostają niezależne kopie danych[1][16]. W HTML Standard opisano także funkcję structuredClone(), która udostępnia ten algorytm jako API do głębokiego kopiowania wartości[17][18]. Dla dużych obiektów binarnych (np. ArrayBuffer) często stosuje się mechanizm transferable objects, w którym własność bufora jest przekazywana do workera bez kosztownego kopiowania[17][19][20].

Worker może tworzyć kolejne workery (tzw. subworkery), przy czym (w typowych przypadkach) obowiązuje ograniczenie do tego samego origin[1]. W klasycznych workerach można też dołączać biblioteki za pomocą funkcji importScripts()[1].

Worker może być uruchamiany jako moduł ES (module worker), co pozwala korzystać z import/export oraz zasad modułów (m.in. domyślnie włącza strict mode)[21]. W HTML Standard zaznaczono ponadto, że w workerach modułowych wywołanie importScripts() automatycznie się nie powiedzie[2].

Standard zwraca uwagę, że workery są relatywnie „ciężkie”: mają zauważalny koszt startu oraz koszt pamięci na instancję, dlatego nie powinno się tworzyć ich w bardzo dużej liczbie[2].

Z punktu widzenia polityk bezpieczeństwa worker ma własny kontekst wykonania, a zasady CSP mogą wymagać osobnej konfiguracji nagłówków dla skryptu workera (z pewnymi wyjątkami dla URL-i typu blob: i data:)[1].

Jeśli potrzebna jest współdzielona pamięć (np. SharedArrayBuffer) między wątkiem głównym a workerem, w nowoczesnych przeglądarkach zwykle wymagane jest środowisko cross-origin isolated (m.in. przez nagłówki COOP/COEP)[22][23].

Przykład użycia

[edytuj | edytuj kod]

Poniżej uproszczony przykład „dedicated workera” do kosztownego obliczenia w tle (schemat komunikacji: postMessageonmessage).[1][24]

main.js

const worker = new Worker("worker.js");

worker.onmessage = (e) => {
  console.log("Wynik z workera:", e.data);
};

worker.postMessage({ from: 1, to: 200000 }); // start obliczeń

worker.js

self.onmessage = (e) => {
  const { from, to } = e.data;

  // Naiwne liczenie liczb pierwszych – celowo kosztowne obliczeniowo
  const primes = [];
  for (let n = Math.max(2, from); n <= to; n++) {
    let isPrime = true;
    for (let d = 2; d * d <= n; d++) {
      if (n % d === 0) { isPrime = false; break; }
    }
    if (isPrime) primes.push(n);
  }

  postMessage({ count: primes.length, last: primes.at(-1) ?? null });
};

Wsparcie w przeglądarkach

[edytuj | edytuj kod]

Według danych „Can I use…”[a] podstawowe web workery (Worker / dedicated) są szeroko wspierane w wersjach głównych przeglądarek desktopowych i mobilnych (Chrome/Edge/Firefox/Safari), natomiast nie są obsługiwane np. w Opera Mini[25].

Funkcja Desktop (Chrome/Edge/Firefox/Safari) iOS Safari Chrome na Androidzie Uwagi
Dedicated worker (Worker) Tak[25] Tak[25] Tak[25] Brak w Opera Mini[25]
Shared worker (SharedWorker)[26] Zwykle tak (zależnie od przeglądarki)[26] Tak w nowszych wersjach (wg tabel wsparcia)[26] Nie (wg tabel wsparcia)[26] Brak w IE; wsparcie mobilne jest nierówne[26]
Worker jako moduł ES (type: "module")[27] Tak w nowoczesnych wersjach[28] Tak w nowszych wersjach[28] Tak w nowszych wersjach[28] Wymaga użycia opcji type w konstruktorze[21][28]

Dodatkowe powiązane API wykorzystywane z workerami mają własne profile wsparcia – przykładowo OffscreenCanvas i SharedArrayBuffer są dostępne w większości nowoczesnych przeglądarek, ale z istotnymi niuansami zależnymi od wersji i konfiguracji bezpieczeństwa[11][29][30].

Ograniczenia

[edytuj | edytuj kod]
  • brak bezpośredniego dostępu do DOM oraz kontekstu window (interfejs użytkownika musi być aktualizowany w wątku głównym)[4][7],
  • narzut komunikacji i serializacji danych (czasem ograniczany przez transferable objects)[19][17],
  • w przypadku niektórych zaawansowanych możliwości (np. współdzielona pamięć) – dodatkowe wymagania bezpieczeństwa, w tym cross-origin isolation (COOP/COEP)[11][31].

Zobacz też

[edytuj | edytuj kod]
  1. stan na styczeń 2026

Przypisy

[edytuj | edytuj kod]
  1. 1 2 3 4 5 6 7 8 9 10 11 Using Web Workers [online], MDN Web Docs, 11 września 2025 [dostęp 2026-01-22] (ang.).
  2. 1 2 3 4 5 6 7 8 9 10 HTML Standard – Web workers [online], WHATWG [dostęp 2026-01-22] (ang.).
  3. Web Workers, WHATWG [dostęp 2023-01-02].
  4. 1 2 3 4 An overview of web workers [online], web.dev [dostęp 2026-01-22].
  5. HTML Living Standard. Html.spec.whatwg.org, 2017-01-31. [dostęp 2017-01-31].
  6. Web Workers [online], W3C, 28 stycznia 2021 [dostęp 2026-01-22] (ang.).
  7. 1 2 3 Use web workers to run JavaScript off the browser's main thread [online], web.dev [dostęp 2026-01-22].
  8. Web Workers API [online], MDN Web Docs, 3 kwietnia 2025 [dostęp 2026-01-22] (ang.).
  9. OffscreenCanvas [online], MDN Web Docs, 26 października 2024 [dostęp 2026-01-22] (ang.).
  10. Using WebAssembly threads from C, C++ and Rust [online], web.dev [dostęp 2026-01-22].
  11. 1 2 3 Making your website "cross-origin isolated" using COOP and COEP [online], web.dev [dostęp 2026-01-22].
  12. A guide to enable cross-origin isolation [online], web.dev [dostęp 2026-01-22].
  13. Worker [online], MDN Web Docs, 30 listopada 2025 [dostęp 2026-01-22] (ang.).
  14. Service Workers [online], Can I use... [dostęp 2026-01-22].
  15. Service Worker API [online], MDN Web Docs, 30 listopada 2025 [dostęp 2026-01-22] (ang.).
  16. The structured clone algorithm [online], MDN Web Docs, 29 czerwca 2025 [dostęp 2026-01-22] (ang.).
  17. 1 2 3 HTML Standard – Structured data [online], WHATWG [dostęp 2026-01-22] (ang.).
  18. Deep-copying in JavaScript using structuredClone [online], web.dev [dostęp 2026-01-22] (ang.).
  19. 1 2 Transferable objects – Lightning fast [online], Chrome for Developers [dostęp 2026-01-22] (ang.).
  20. Transferable objects [online], MDN Web Docs, 18 września 2025 [dostęp 2026-01-22] (ang.).
  21. 1 2 Worker() constructor [online], MDN Web Docs [dostęp 2026-01-22] (ang.).
  22. SharedArrayBuffer [online], MDN Web Docs, 30 listopada 2025 [dostęp 2026-01-22] (ang.).
  23. Why you need "cross-origin isolated" for powerful features [online], web.dev, 4 maja 2020 [dostęp 2026-01-22] (ang.).
  24. A concrete web worker use case [online], web.dev [dostęp 2026-01-22].
  25. 1 2 3 4 5 Web Workers [online], Can I use… [dostęp 2026-01-22] (ang.).
  26. 1 2 3 4 5 Shared Web Workers [online], Can I use... [dostęp 2026-01-22] (ang.).
  27. Worker API: Worker() constructor: Support for ECMAScript modules [online], Can I use... [dostęp 2026-01-22].
  28. 1 2 3 4 JavaScript modules in workers [online], Can I use… [dostęp 2026-01-22] (ang.).
  29. OffscreenCanvas [online], Can I use... [dostęp 2026-01-22].
  30. Shared Array Buffer [online], Can I use... [dostęp 2026-01-22].
  31. Why you need "cross-origin isolated" for powerful features [online], web.dev [dostęp 2026-01-22].

Linki zewnętrzne

[edytuj | edytuj kod]