Modül çalışanlarıyla web'de mesaj dizisi oluşturma

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