Web Workers — interfeysni qotirmaydigan hisob-kitob
Bir xil og‘ir vazifa: asosiy oqimda u sahifani muzlatadi, Web Worker‘da esa fonda hisoblanadi — spinner va FPS uzilmaydi. Farqni jonli his qiling.
Brauzerdagi JS bitta oqimli: og‘ir sikl hisoblanayotganda sahifa chizilmaydi ham, bosishga javob bermaydi ham. Buni so‘z bilan emas, qo‘l bilan ko‘rsatmoqchi edim — qotishni barmoq bilan sezish mumkin bo‘lsin, va yonida worker uni qanday olib tashlashini ko‘rsatay.
Worker — bu “asinxronlik” emas, haqiqiy ikkinchi OS oqimi. U rostdan parallel hisoblaydi, lekin DOM‘ga kira olmaydi va faqat postMessage orqali gaplashadi (structured clone ma’lumotni nusxalaydi). Katta massivlar uchun transferable-buferlar bor — nusxasiz, nanosekundlarda uzatiladi.
Birinchi variant worker‘ni Blob-URL‘dan yaratardi — kamroq fayl. Ammo saytning qat’iy CSP‘si (default-src self, blob: yo‘q) uni bloklab qo‘ydi. Worker‘ni statik fayl /workers/heavy-task.js sifatida berdim va CSP‘ga worker-src self qo‘shdim — bu ancha toza: inline kod o‘rniga same-origin.
Interfeys nega umuman qotadi
Brauzerdagi JavaScript bitta oqimda ishlaydi. O‘sha oqim kodingizni ham hisoblaydi, sahifani ham joylashtiradi, kadr ham chizadi va bosishlarga ham javob beradi. U bir necha soniya sinxron siklda band bo‘lsa — sahifa o‘lik: animatsiyalar to‘xtaydi, tugmalar bosilmaydi, matn maydonidagi kursor miltillamaydi.
Quyida requestAnimationFrame‘ga asoslangan jonli indikator (spinner, FPS va «puls»). **«Asosiy oqimda»**ni bosing — o‘sha rAF sikli band oqimda yashaydi, shuning uchun hisob vaqtida hammasi qotadi. Keyin **«Web Worker‘da»**ni bosing va farqni his qiling.
Bu qanday ishlaydi
new Worker('/workers/heavy-task.js') alohida oqim ko‘taradi. Aloqa — faqat xabarlar orqali:
// asosiy oqim
worker.postMessage(40_000_000);
worker.onmessage = (e) => console.log(e.data.ms);
// worker.js — o‘zining global konteksti, window va DOM yo‘q
self.onmessage = (e) => {
let acc = 0;
for (let i = 0; i < e.data; i++) acc += Math.sqrt(i) * Math.sin(i);
self.postMessage({ acc });
};Demodagi og‘ir hisob (40 mln iteratsiyada √·sin) ikkala holatda ham bir xil — faqat qayerda bajarilishi o‘zgaradi. Asosiy oqimda UI qotishi ≈ vazifa vaqtiga teng; worker‘da esa har kadr uchun barqaror ~16 ms.
Worker’lar yana nima qila oladi
Bu eng ko‘rgazmali holat, lekin yagona emas:
- Fondagi so‘rov va parsing — katta JSON‘ni renderni osib qo‘ymay tortib olish va tahlil qilish.
- SharedWorker — bir nechta varaq uchun bitta oqim: umumiy soket, bitta saytning oynalari orasida holatni sinxronlash.
- OffscreenCanvas + transferable — rasmlarni to‘g‘ridan-to‘g‘ri worker ichida filtrlash/dekodlash, piksellarni nusxasiz bufer sifatida qaytarish.
Har biri alohida yozuvga arziydi; bu yerda ildizni ko‘rsatish muhim edi: og‘irni chizadigan joyda hisoblama.