Web çalışanlarındaki JavaScript modülleri sayesinde ağır işleri arka plandaki ileti dizilerine taşımak artık daha kolay.
JavaScript tek iş parçacıklı olduğundan aynı anda yalnızca bir işlem gerçekleştirebilir. Bu ve web'deki birçok durumda iyi sonuç verir, ancak ihtiyaç duyduğumuzda sorun yaratabilir. veri işleme, ayrıştırma, hesaplama veya analiz gibi ağır işleri yapabilirler. Gün geçtikçe daha fazla karmaşık uygulamalar web üzerinde dağıtılsa da çoklu iş parçacıklarına bahsedeceğim.
Web platformunda iş parçacığı oluşturma ve paralellik için başlıca temel unsur Web Workers API. Çalışanlar, işletim sisteminin ötesindeki basit bir soyut kavramdır API geçiren bir mesajı açığa çıkaran mesaj dizileri uygun bir tekniktir. Bu yöntem, yüksek maliyetli hesaplamalar yaparken veya büyük veri kümelerinde çalışarak, ana iş parçacığının ve arka plan iş parçacığı üzerinde pahalı işlemlere neden olabilir.
Bir çalışan komut dosyasının ana makineden gelen iletileri dinlediği, çalışan kullanımına dair tipik bir örnek ileti dizisinde ve kendi mesajlarını göndererek yanıt verir:
page.js:
const worker = new Worker('worker.js');
worker.addEventListener('message', e => {
console.log(e.data);
});
worker.postMessage('hello');
worker.js:
addEventListener('message', e => {
if (e.data === 'hello') {
postMessage('world');
}
});
Web Worker API, on yılı aşkın süredir çoğu tarayıcıda kullanılmaktadır. O sırada çalışanların mükemmel bir tarayıcı desteğine sahip olduğu ve iyi optimize edildiği anlamına gelir. Ayrıca, JavaScript modüllerinden önce gelir. Çalışanlar tasarlanırken modül sistemi olmadığından API, bir çalışana kod yüklemek ve komut dosyaları oluşturmak için kullanılan zaman uyumlu komut dosyasına benzer kaldı yaygın olarak kullanılan yükleme yaklaşımlarını inceledik.
Tarih: klasik çalışanlar
Çalışan oluşturucu bir klasik
komut dosyası URL'si
ilişkili olması gerekir. Hemen yeni çalışan örneğine bir referans döndürür.
Bu işlem, mesajlaşma arayüzünün yanı sıra anında duran ve hemen duran bir terminate()
yöntemini gösterir.
ortadan kaldırır.
const worker = new Worker('worker.js');
Web çalışanlarının içinde ek kod yüklemek için bir importScripts()
işlevi kullanılabilir. Ancak bu işlev
her bir komut dosyasını getirmek ve değerlendirmek için çalışanın yürütülmesini duraklatır. Ayrıca komut dosyalarını yürütür
Klasik <script>
etiketi gibi global kapsamda çalışır. Yani bir komut dosyasındaki değişkenler
başka birindeki değişkenlerin üzerine yazılır.
worker.js:
importScripts('greet.js');
// ^ could block for seconds
addEventListener('message', e => {
postMessage(sayHello());
});
greet.js:
// global to the whole worker
function sayHello() {
return 'world';
}
Bu nedenle, web çalışanları tarih boyunca bir web sitesinin mimarisine çok büyük bir etki
bir uygulamadır. Geliştiriciler, bu değişiklikleri uygulayabilmeleri için zekice araçlar ve geçici çözümler
modern geliştirme uygulamalarından vazgeçmeden web çalışanlarını nasıl kullanabileceğini açıkladık. Örneğin paketleyiciler
örneğin,
webpack, importScripts()
kullanan, oluşturulan koda bir küçük modül yükleyici uygulaması yerleştirdi
ancak değişken çakışmalarını önlemek ve simüle etmek için modülleri fonksiyonlarla sarmalar.
içe ve dışa aktarımına yardımcı olur.
Modül çalışanlarını girin
Web çalışanları için JavaScript'in ergonomisi ve performans avantajlarıyla yeni bir mod
modülleri Chrome 80'de gönderilmektedir. Buna modül çalışanları adı verilir. İlgili içeriği oluşturmak için kullanılan
Worker
oluşturucu artık yeni bir {type:"module"}
seçeneğini kabul ediyor. Bu seçenek, komut dosyası yüklemeyi ve
<script type="module">
ile eşleşecek şekilde yürütme işlemi.
const worker = new Worker('worker.js', {
type: 'module'
});
Modül çalışanları standart JavaScript modülleri olduğundan, içe ve dışa aktarma ifadelerini kullanabilirler. Farklı tüm JavaScript modülleriyle, bağımlılıklar belirli bir bağlamda (ana iş parçacığı, çalışanı vb.) gerektirir ve gelecekteki tüm içe aktarma işlemleri halihazırda yürütülen modül örneğine referans verir. Yükleme JavaScript modüllerinin yürütülmesi de tarayıcılar tarafından optimize edilir. Bir modülün bağımlılıkları tüm modül ağaçlarının otomatik olarak yüklenmesini sağlayan, modül yürütülmeden önce kullanabilirsiniz. Modül yükleme, ayrıştırılmış kodu da önbelleğe alır. Bu, iş parçacığının ve bir çalışandaki iş parçacığının yalnızca bir kez ayrıştırılması gerekir.
JavaScript modüllerine geçmek, dinamik
kodu yürütülmesini engellemeden geç yükleme kodu için içe aktarma
ne ifade ettiğine bakacağız. Dinamik içe aktarma, bağımlılıkları yüklemek için importScripts()
kullanmaktan çok daha açık bir yöntemdir.
çünkü içe aktarılan modülün dışa aktarımları, genel değişkenlere güvenmek yerine döndürülür.
worker.js:
import { sayHello } from './greet.js';
addEventListener('message', e => {
postMessage(sayHello());
});
greet.js:
import greetings from './data.js';
export function sayHello() {
return greetings.hello;
}
En iyi performans için eski importScripts()
yöntemi modül içinde bulunmamaktadır
birlikte çalışır. Çalışanların JavaScript modüllerini kullanacak şekilde değiştirilmesi, tüm kodun yüksek düzey
mod'u seçin. Diğer
önemli değişiklik, bir JavaScript modülünün üst düzey kapsamındaki this
değerinin
undefined
ise klasik çalışanlarda değer, çalışanın global kapsamıdır. Neyse ki
her zaman için global kapsama referans sağlayan bir self
global olmuştur. Sunulduğu yerler
hizmet çalışanları dahil olmak üzere tüm çalışan türlerini kapsar.
modulepreload
ile çalışanları önceden yükleyin
Modül çalışanlarının sağladığı önemli performans iyileştirmelerinden biri,
ve bağımlılıklarını konuştuk. Modül çalışanlarıyla, komut dosyaları standart olarak yüklenir ve yürütülür
JavaScript modüllerinin kapsamı, modulepreload
kullanılarak önceden yüklenebilir ve hatta önceden ayrıştırılabilir:
<!-- preloads worker.js and its dependencies: -->
<link rel="modulepreload" href="worker.js">
<script>
addEventListener('load', () => {
// our worker code is likely already parsed and ready to execute!
const worker = new Worker('worker.js', { type: 'module' });
});
</script>
Önceden yüklenmiş modüller hem ana iş parçacığı hem de modül çalışanları tarafından da kullanılabilir. Bu, özellikle veya önceden öğrenmenin mümkün olmadığı durumlarda modülün ana iş parçacığında mı yoksa bir çalışanda mı kullanılacağı.
Önceden, web çalışanı komut dosyalarını önceden yüklemek için kullanılabilecek seçenekler sınırlıydı ve
her zaman güvenilir olmalıdır. Klasik çalışanların kendi "çalışanı" vardı Önceden yükleme için bir kaynak türü var, ancak
tarayıcılarda <link rel="preload" as="worker">
uygulandı. Sonuç olarak, birincil teknik
%100'den fazla yöntemi olan <link rel="prefetch">
, tamamen farklı bir platform
üzerinde değişiklik yapalım. Doğru önbelleğe alma başlıklarıyla birlikte kullanıldığında
çalışan örneklendirmesinin, çalışan komut dosyasını indirmek için beklemek zorunda kalmasını önlemek amacıyla kullanılır. Ancak,
modulepreload
Bu teknik, önceden yükleme bağımlılıklarını veya önceden ayrıştırmayı desteklemiyordu.
Paylaşılan çalışanlar ne olacak?
Paylaşılan çalışanlar,
, Chrome 83 itibarıyla JavaScript modülleri desteğiyle güncellenmiştir. Bağlı çalışanlar gibi
{type:"module"}
seçeneğiyle paylaşılan bir çalışan oluşturmak artık çalışan komut dosyasını
modülünü kullanabilirsiniz:
const worker = new SharedWorker('/worker.js', {
type: 'module'
});
JavaScript modüllerinin desteklenmesinden önce SharedWorker()
oluşturucusu yalnızca bir
URL ve isteğe bağlı bir name
bağımsız değişkeni. Bu, klasik paylaşılan çalışan kullanımında da çalışmaya devam eder; ancak
modülle paylaşılan çalışanları oluşturmak, yeni options
bağımsız değişkeninin kullanılmasını gerektirir. Mevcut
seçenekleri
özel bir çalışanla aynıdır, name
önceki name
bağımsız değişkeni.
Service Worker'ın durumu nedir?
Service Worker spesifikasyonu Google'ın
bir güncellemenin kabul edilmesini desteklemek üzere
giriş noktası olarak JavaScript modülü, modül çalışanlarıyla aynı {type:"module"}
seçeneğini kullanır ve
Ancak bu değişiklik henüz tarayıcılara uygulanmadı. Bu gerçekleştikten sonra,
aşağıdaki kodu kullanarak JavaScript modülü kullanarak bir hizmet çalışanı örneği oluşturmak için:
navigator.serviceWorker.register('/sw.js', {
type: 'module'
});
Spesifikasyon güncellendiği için tarayıcılar yeni davranışı uygulamaya başladı. Bu işlem zaman alır çünkü JavaScript getirme ile ilişkili bazı ek sorunlar vardır hizmet çalışanlarına entegre eder. Hizmet çalışanı kaydının içe aktarılan komut dosyalarını karşılaştırması gerekir aynı işlem gerçekleştirildiğinde önceki bir güncellemenin tetiklenip tetiklenmeyeceğini belirler ve bunun JavaScript modülleri için uygulanması gerekir kullandığında önemlidir. Ayrıca, hizmet çalışanları önbelleğine alma olup olmadığını kontrol edin.
Ek kaynaklar ve daha fazla bilgi
- Özellik durumu, tarayıcı fikir birliği ve standartlaştırma
- Orijinal modül çalışanlarına özellik ekleme
- Paylaşılan çalışanlar için JavaScript modülleri
- Service Worker'lar için JavaScript modülleri: Chrome uygulama durumu