Web Worker๋ž€

single-threaded JS์˜ ํ•œ๊ณ„

๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ†ตํ•ด UI๋Š” ๋ธ”๋ฝ๋˜์ง€ ์•Š๊ณ  ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด, Web API๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ผ๋ฐ˜ ์ฝ”๋“œ๊ฐ€ CPU๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—” ์–ด๋–จ๊นŒ?

let i = 0;
while (i < 10 ** 10) {}

์œ„์˜ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋™์•ˆ, ๋‹ค๋ฅธ ์ฝ”๋“œ๋“ค์€ ์‹คํ–‰๋  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ํŽ˜์ด์ง€๊ฐ€ ๋ฉˆ์ถฐ์ง€๋Š” ํ˜„์ƒ์ด ๋ฐœ์ƒํ•œ๋‹ค.

์ด๊ฒƒ์ด single-thread์ธ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ํ•œ๊ณ„์ด๋‹ค. HTML5์— ์ถ”๊ฐ€๋œ web worker๋Š” ์ด๋Ÿฌํ•œ ํ•œ๊ณ„๋ฅผ ํ•ด์†Œ์‹œ์ผœ์ค€๋‹ค.

Web Worker๋Š” ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ์•„๋‹Œ ์ƒˆ๋กœ์šด thread์—์„œ parallelํ•˜๊ฒŒ ์‹คํ–‰๋œ๋‹ค. ์ƒ๋‹นํžˆ ์˜ค๋žœ ์‹œ๊ฐ„ ๋™์•ˆ ๊ณ„์‚ฐ์ด ํ•„์š”ํ•œ ์ž‘์—…์„ web worker๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๊ณ„์‚ฐํ•˜๋„๋ก ํ•œ๋‹ค๋ฉด, UI๊ฐ€ ๋ธ”๋ฝ๋˜๋Š” ์ผ์€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.

Web Workers์˜ ์ข…๋ฅ˜

web worker๋Š” ์„ธ ์ข…๋ฅ˜๊ฐ€ ์žˆ๋‹ค.

  • Dedicated Workers web worker๋ฅผ ํ˜ธ์ถœํ•œ ์Šคํฌ๋ฆฝํŠธ์—์„œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

  • Shared Workers ๊ฐ™์€ origin์—์„œ ๋™์ž‘ํ•˜๋Š” ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹ค๋ฅธ ๋ธŒ๋ผ์šฐ์ € ํƒญ, iframe, ์‹ฌ์ง€์–ด๋Š” worker์—์„œ๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

  • Service Worker event driven ์›Œ์ปค์ด๋‹ค.

Web Workers ๋™์ž‘ ๋ฐฉ์‹

์›น ์›Œ์ปค๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋…๋ฆฝ๋œ ์Šค๋ ˆ๋“œ์—์„œ ๋™์ž‘ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์›น ์›Œ์ปค๋กœ ๋™์ž‘ํ•  ์ฝ”๋“œ๋ฅผ ๋‹ค๋ฅธ ํŒŒ์ผ์— ์ ์–ด์•ผ ํ•œ๋‹ค.

์›น ์›Œ์ปค๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

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

worker.js ํŒŒ์ผ์ด ์กด์žฌํ•˜๊ณ , ์ ‘๊ทผ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด, ๋ธŒ๋ผ์šฐ์ €๋Š” ์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค์–ด๋‚ด์„œ, ๋น„๋™๊ธฐ์ ์œผ๋กœ ํ•ด๋‹น ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œํ•œ๋‹ค.

์ƒ์„ฑ๋œ ์›น ์›Œ์ปค๋ฅผ ์‹œ์ž‘ํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด, postMessage ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

// main thread
myWorker.postMessage([first, second]);

์›น ์›Œ์ปค์—์„œ๋Š” onmessage ๋ฉ”์„œ๋“œ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. ๋ฉ”์„ธ์ง€๋Š” event ๊ฐ์ฒด์˜ data ์†์„ฑ์— ๋„˜์–ด์˜ค๊ฒŒ ๋œ๋‹ค.

์›น ์›Œ์ปค์—์„œ๋„ postMessage๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

//worker.js
onmesesage = function (e) {
  const [first, second] = [e.data[0], e.data[1]];
  postMessage("send from web worker");
};

๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ๋Š” ์›น ์›Œ์ปค์—์„œ ์ „๋‹ฌํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ onmessage๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

myWorker.onmessage = function (e) {
  const response = e.data;
};

์›Œ์ปค๋ฅผ ์ข…๋ฃŒ์‹œํ‚ฌ ๋•Œ๋Š” main thread์—์„œ myWorker.terminate()๋กœ ์ข…๋ฃŒ์‹œํ‚ค๊ฑฐ๋‚˜, ์›Œ์ปค์—์„œ close()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์Šค์Šค๋กœ ์ข…๋ฃŒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

์›น ์›Œ์ปค์™€ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ ์‚ฌ์ด์—์„œ ์ „๋‹ฌ๋˜๋Š” ๋ฉ”์„ธ์ง€๋Š” ๊ณต์œ ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค. ๋ฉ”์„ธ์ง€๋Š” ๋ณต์‚ฌ๋˜๊ฑฐ๋‚˜ ์ „๋‹ฌ๋œ๋‹ค.

๋ฉ”์„ธ์ง€๊ฐ€ ๋ณต์‚ฌ๋˜๋Š” ๊ฒฝ์šฐ, ์ง๋ ฌํ™”(serialized)๋˜์–ด ๋ณต์‚ฌ๋œํ›„, ์ „๋‹ฌ๋˜๊ณ , ๋‹ค์‹œ ์—ญ์ง๋ ฌํ™”(deserialized)๋œ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ด ๋ฐฉ์‹์„ JSON encoding/decoding ํ•˜๋Š” ์‹์œผ๋กœ ๊ตฌํ˜„ํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์€ ๋ฉ”์‹œ์ง€๊ฐ€ ์ „์†ก๋˜๋Š”๋ฐ, ์ƒ๋‹นํžˆ ํฐ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฉ”์„ธ์ง€๊ฐ€ ํด ์ˆ˜๋ก, ์ „๋‹ฌํ•˜๋Š”๋ฐ ๋” ์˜ค๋ž˜๊ฑธ๋ฆฐ๋‹ค.

๋ฉ”์„ธ์ง€๊ฐ€ ์ „๋‹ฌ๋  ๊ฒฝ์šฐ, ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ธ ์ชฝ์—์„œ๋Š” ๊ทธ ๊ฐ’์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. ์ด ๋ฐฉ์‹์€ ์˜ค์ง ArrayBuffer๋งŒ ์ „์†กํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ํ•œ๊ณ„๊ฐ€ ์žˆ๋‹ค.

์›น ์›Œ์ปค์˜ ํ•œ๊ณ„

์›น ์›Œ์ปค์—์„œ ์ง์ ‘ DOM ์กฐ์ž‘์„ ํ•  ์ˆ˜ ์—†๊ณ , window ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋‚˜ ์†์„ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. ์›น ์›Œ์ปค์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” API๋Š” ์ด ์‚ฌ์ดํŠธ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์›น ์›Œ์ปค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์€ ๊ฒฝ์šฐ

  • ์•”ํ˜ธํ™”

  • ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ fetchํ•˜๊ธฐ

    • data๋ฅผ ๋กœ๋“œํ•ด์˜ค๋Š” ์‹œ๊ฐ„์„ ๊ฐœ์„ ํ•˜๊ณ , ์›น ์‚ฌ์ดํŠธ๋ฅผ ์ตœ์ ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์›น ์›Œ์ปค๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ๋กœ๋“œํ•ด์„œ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฐธ๊ณ 

Last updated