Curt Poem

프론트 엔드 공부와 지식 나눔을 위한 블로그

개발/JavaScript 26

워커를 더 효율적으로 사용하는 워커풀(Worker Pool) 개발기

이미지 처리 작업은 생각보다 리소스를 많이 소모합니다. 특히 사용자가 가지고 있는 고해상도 이미지를 썸네일로 변환하는 과정에서는, 성능뿐만 아니라 메모리 관리까지도 신경 써야 했습니다. 이러한 문제를 해결하기 위해 웹 워커(Web Worker)를 활용한 워커풀(Worker Pool) 클래스를 직접 설계하게 되었는데요, 이 글에서는 그 과정을 정리해보았습니다.워커를 사용하자이미지를 썸네일 크기로 전환하는 것은 아주 빠른 작업이긴 하지만 많은 이미지를 처리한다면 사용자와의 상호작용이 생각보다 오랜 시간 차단될 수 있습니다. 그래서 이미지 처리를 메인쓰레드에서 하는 대신 워커에 작업을 맡겨 메인 쓰레드의 부담을 줄이고 사용자의 상호작용을 차단하지 않게 만들 수 있습니다. 그래서 당연히 Web Worker를 사..

개발/JavaScript 2025.04.13

자바스크립트와 멀티 쓰레드 3 - 다른 형태의 워커(사실 의미가 적은 글)

자 지금까지 다양한 종류의 워커를 알아보았습니다. 사실 Shared Worker와 Service Worker는 단순 추가적인 쓰레드를 활용한다기 보다는 특별한 종류의 작업을 처리하는 것에 더 가까운 것같습니다. 제목인 자바스크립트와 "멀티 쓰레드"와는 조금 맞지 않은 부분이 있습니다.(제목을 자바스크립트와 워커들 같은 식으로 지었어야했나봅니다.) 하지만 오늘 다룰 워커는 멀티 쓰레드라는 제목과 가까운 워커입니다. 바로 Dedicated Worker인데요. 한국말로 번역해 보자면 전용 워커 정도가 될 것입니다. Dedicated는 "헌식적인"이라는 뜻도 있지만 "특정한 목적을 위한"이라는 뜻도 있습니다. 그리고 Dedicated Worker는 이 뜻에 훨씬 잘 들어 맞죠. 그리고 별 다른 언급없이 워커를 ..

개발/JavaScript 2025.02.23

자바스크립트와 멀티 쓰레드 3 - Service Worker로 백그라운드에서 네트워크다루기

웹 애플리케이션에서 중요하게 여겨지는 점 중 하나는 네트워크 최적화입니다. 네트워크와 관련해서 다양한 요청을 캐싱하고, 캐싱한 데이터를 적절한 타이밍에 업데이트하고, 인터넷 연결이 불안정한 상황에서도 최소한의 확실한 동작을 보장하는 것이 중요한 문제입니다. AXIOS, Tanstack Query 등 네트워크와 관련한 다양한 라이브러리가 인기있는 이유이기도 합니다. 이번에는 백그라운드에서 네트워크 요청을 다루며, 다양하게 활용할 수 있는 Service Worekr에 대해 다루어보겠습니다. Service WorekrServie Workeer는 다른 Worker들과 마찬가지로 메인 쓰레드가 아닌 별도의 쓰레드에서 관리되는 Worker입니다. 특히, 네트워크 요청 가로채기(intercept), 요청 캐싱 등을 ..

개발/JavaScript 2025.02.08

자바스크립트와 멀티 쓰레드 2 - Shared Worker로 여러 탭과 창의 데이터를 공유하기(+추상화하여 메모리 관리하기)

Shared Worker와 Service Worker는 이전 글에서 언급하였듯이 데이터 공유와 비동기 작업을 효율적으로 처리하기 위해 제공되는 Web Worker의 확장된 인터페이스입니다. 두 Worker모두 메인 쓰레드와 분리되어 독립된 스레드에서 실행되며, 성능 최적화를 통한 사용자의 경험 향상을 위해 사용할 수 있습니다.Shared WorkerShared Worker는 동일한 출처(origin)에서 실행되는 여러 브라우저 탭, iframe, 또는 웹 애플리케이션 간에 공유될 수 있는 Worker입니다. 만약 브라우저의 서로 다른 탭(tab)이더라도 같은 출처를 가진다면 모두가 동일한 Worker에 접근 가능합니다. 그래서 만약 여러 개의 탭이나 윈도우 창이 켜져있더라도 모두 같은 데이터를 공유받거나..

개발/JavaScript 2025.01.28

자바스크립트와 멀티 쓰레드 1 - 자바스크립트가 싱글 쓰레드라고 불리는 이유와 Worker로 여러 개의 쓰레드 사용하기

자바스크립트는 싱글 쓰레드 언어로 널리 알려져 있습니다. 하지만 브라우저의 Web Worker, 노드의 Worker Thread를 활용하면 멀티 쓰레드 환경을 구현할 수 있습니다. 자바스크립트로 멀티 쓰레드 환경을 구현하는 방법을 알아보기 전에 멀티 쓰레드 환경을 구현할 수 있음에도 싱글 쓰레드 언어라고 소개하는 지 짚어보고 넘어가도록 하겠습니다.자바스크립트는 싱글 쓰레드 언어?자바스크립트의 기본 실행 환경은 단일 쓰레드 환경입니다. 즉, 자바스크립트는 하나의 호출 스택에서 한번의 하나의 작업이 처리된다는 뜻입니다. 이런 작업의 처리는 브라우저든, Node 환경이든 메인 이벤트 루프에서 관리되며 순차적으로 처리됩니다. DOM 조작, 이벤트 처리, UI 업데이트 등의 거의 모든 자바스크립트 동작은 메인 쓰..

개발/JavaScript 2025.01.11

자바스크립트 await는 이벤트 루프 내에서 어떻게 동작할까

지난 글에서 태스크 큐를 통해 자바스크립트의 코드 실행 순서를 알아보았습니다. 하지만 한 가지 의문점이 생겼는데요. Promise 객체는 마이크로 태스크 큐로 들어가지만 만약 await 키워드를 사용한다면 어떻게 될까요? 함수의 실행을 일시 정지하고 Promise가 resolve(혹은 reject) 될까지 기다린다는 사실은 알고 있을 겁니다. 하지만 이벤트 루프에서 어떻게 처리가 될까요? Promise가 fullfilled 혹은 rejected 될 때까지 이벤트 루프의 작동도 멈출까요?async / awaitasync와 await는 JavaScript에서 비동기 처리를 보다 읽기 쉽게 작성할 수 있도록 도와주는 문법입니다. 기본적으로 비동기 코드를 처리할 때 주로 Promise를 사용하게 되는데, asy..

개발/JavaScript 2024.10.23

동적 배열을 사용하는 자바스크립트에서 일어나는 일

최근 오픈소스에 기여를 하게 되었는데요. 그동안 번역 혹은 오역의 수정만 했지만 이번에는 코드를 수정한 것이 오픈소스 라이브러리에 반영되었습니다. 버그를 수정한 것은 아니고 성능을 향상시킨 수정이었는데요. 사실 정말 간단한 수정이었습니다. 배열을 만들 때, 새로운 빈 배열에 값을 계속 추가하는 방식에서 미리 배열의 크기를 정해놓고 인덱스에 맞게 값을 수정하는 방식이었습니다. 작은 수정이었지만 성능은 놀랍게도 약 47% 향상되었습니다.왜 이런 사소한 변화가 성능에 이토록 큰 영향을 주었을까요?동적 배열배열이란?배열과 같은 데이터 구조는 일반적으로 메모리에 순서대로, 연속해서 저장됩니다. 예를 들어 첫 번째 요소가 메모리의 주소 0x1000에 있다면, 배열의 두 번째 요소는 그 다음 메모리 주소(0x1000..

개발/JavaScript 2024.10.15

자바스크립트의 연산자 우선순위(feat. 이산수학 한 방울)

수학에서 여러 연산들이 복합적으로 사용될 때 연산자들 간에 우선 순위가 있는 것처럼 자바스크립트의 다양한 연산자들 사이에도 우선순위가 존재합니다. 이 우선 순위에 따라 연산자들이 평가되는 순서가 달라지게 됩니다. 사칙연산과 같은 경우는 수학과 일치하지만 다음과 같은 코드들의 결과를 예측하기는 쉽지 않습니다.let foo = {n: 1};let bar = foo;foo.x = foo = {n: 2};// foo와 bar의 값은?let i = 3;console.log(i++ + ++i * 2);// 출력 값은?let a = 10;let b = 20;a += b -= 5;// a, b 각각의 값은?let p = 5; // 0101 (2진수)let q = 3; // 0011 (2진수)console.log(p..

개발/JavaScript 2024.10.12

태스크큐를 중점으로 자바스크립트 코드의 실행 순서를 알아보자

자바스크립트 런타임은 콜 스택(Call Stack), 태스크 큐(Task Queue), 마이크로태스크 큐(Microtask Queue), 이벤트 루프(Event Loop)로 구성되어 있습니다. 이 이벤트 루프가 어떻게 동작하는지 잘 이해하고 있어야 최적화나 올바른 아키텍처 설계가 가능해집니다. 다음의 코드 실행 결과가 어떻게 될지 아시나요? console.log('Start');setTimeout(() => { console.log('setTimeout done');}, 0);Promise.resolve().then(() => { console.log('promise resolved');});console.log('End');정답은 다음과 같습니다.StartEndpromise resolvedsetTi..

개발/JavaScript 2024.09.25

자바스크립트 제너레이터(Generator)로 반복가능한 객체 이터레이터(iterator)를 만들자(feat. 파이썬의 range 구현하기)

Iterator이터레이터는 반복 가능한 객체를 순회할 수 있게 해주는 객체입니다. 조금 더 구체적으로 표현하자면 이터레이터는 이터러블 객체를 반환하는 Symbol.iterator 메서드를 구현한 객체입니다. 이터러블 객체(Iterable Object)는 자바스크립트에서 반복 가능한 객체를 의미합니다. 이터러블 객체는 반복 작업을 지원하며, for...of 루프나 스프레드 연산자, 배열 디스트럭처링 등 다양한 자바스크립트 문법에서 사용할 수 있습니다. 이터러블 객체는 Symbol.iterator라는 특수한 메서드를 가지고 있습니다. 이 메서드는 이터레이터를 반환해야 하며, 이터레이터는 next 메서드를 통해 반복 작업을 처리합니다. next 메서드는 { value, done } 형태의 객체를 반환하며, 다..

개발/JavaScript 2024.07.28

JSDoc에서 제네릭과 타입단언 사용하기

지난번에 JSDoc으로 더 나은 주석 작성하기, 그리고 개발 관련 도서 추천이라는 글을 썻었는데요. JSDoc으로 함수, 클래스, 변수에 설명을 추가할 뿐만 아니라 타입을 지정해 주어 쉽게 파악이 가능한 주석을 작성하는 법을 포스팅했습니다. 오늘은 이 JSDoc을 이용하여 ts 파일이 아닌 js 파일에서도 타입을 검사할 수 있게 만드는 법을 포스팅하겠습니다. 더불어 타입스크립트처럼 사용할 수 있도록 제넥릭과 타입 캐스팅 같이 조금 더 심화된 사용법을 설명해드리겠습니다.JS 파일에서 타입검사하기// @ts-check파일의 최상단에 위와 같은 키워드를 붙이면 js 파일에서도 타입스크립트와 같은 타입검사가 가능합니다. 이 키워드를 사용한다면 JavaScript 파일에 타입 정보와 주석을 추가하여 코드의 타입 ..

개발/JavaScript 2024.07.21

package.json 알아보기(feat. Semantic Versioning & Peer Dependencies)

JavsScript를 사용하여 개발을 한다면 npm을 이용해 외부 라이브러리 혹은 프레임 워크를 사용해 본 경험이 있을 것입니다. npm을 실행한다면 프로젝트의 루트 디렉토리에 package.json이라는 파일이 생성됩니다. 보통 의존성을 관리하기 위한 문서로 생각하고 있지만 그 외에도 몇 가지 역할을 더 하고 있습니다.package.json다른 사람이 개발한 패키지를 쉽게 관리하고 설치할 수 있도록 도와주는 파일이라고 정리하고 있습니다. 그리고 더 구체적으로는 다음의 3가지 기능을 언급하고 있습니다.프로젝트가 의존하는 패키지 목록시맨틱 버전 관리 규칙을 사용하여 패키지의 버전을 지정빌드를 재현 가능하게 만들어서 다른 개발자들과 쉽게 공유할 수 있게 함name과 versionpackage.json은 반드..

개발/JavaScript 2024.06.23

JavaScript의 렉시컬 환경과 클로저, 조금 더 자세하게 알아보자

let globalVariable = "글로벌 변수";function logOuterVariable() { console.log(globalVariable);}위의 코드와 같이 자바스크립트에서는 함수가 함수 외부의 변수에 접근할 수 있습니다. 함수는 어떤 기준으로 외부의 변수에 접근하는 것일까요? 이는 렉시컬 환경과 큰 연관이 있습니다. 렉시컬 환경은 코드가 작성된 시점의 변수 스코프와 그 접근 권한을 정의하는 환경으로 함수가 선언되는 순간 결정됩니다. 그리고 이 렉시컬 환경을 기억하고 그 환경에 접근할 수 있는 함수를 뜻합니다.렉시컬 환경(Lexical Environment)먼저, 외부 변수에 접근하는 함수를 생성해 보겠습니다. 외부 변수에 접근하는 함수의 예시치고는 복잡하지만 렉시컬 환경부터 클로저..

개발/JavaScript 2024.06.10

JSDoc으로 더 나은 주석 작성하기, 그리고 개발 관련 도서 추천

라이브러리를 사용하다 보면 함수를 작성할 때 해당 함수의 설명이 작성된 경우를 볼 수 있습니다. 이런 설명을 보다보면 함수의 사용법을 더 쉽게 파악할 수 있게 됩니다. 이 기능은 JSDoc라는 기능을 이용한 것으로, 자바스크립트 뿐만 아니라 Java(JavaDoc), python(docstring) 등 다양한 언어에서 지원하며 문법도 거의 똑같다고 합니다. JSDoc을 사용하면 함수의 설명 뿐만 아니라 파라미터와 반환 값의 타입에 대한 정보도 지원해 줄 수 있습니다. 파라미터와 반환값의 타입을 컴퓨터도 알게 되니 타입스크립트처럼 자동완성이 각 타입에 맞게 추천됩니다. 일반 주석과 다른 점은 VSCode와 같은 편집기를 이용한다면 해당 함수가 작성된 곳이 아닌 사용되는 곳에서도 내용을 확인할 수 있다는 것..

개발/JavaScript 2024.06.03

웹 컴포넌트로 재사용 가능한 커스텀 HTML 엘리먼트를 생성하기

웹 컴포넌트는 HTML, CSS, 자바스크립트를 활용하여 재사용 가능하고 캡슐화된 웹 요소를 만드는 도구입니다. 웹 컴포넌트는 표준 웹 기술을 사용하여 구현하기 때문에 웹 프레임워크나 라이브러리에 의존하지 않고 개발할 수 있습니다. 덕분에 다양한 환경에서 사용될 수 있고, 개발자가 선택할 수 있는 유연성을 제공합니다.웹 컴포넌트웹 컴포넌트는 React나 Vue에서 말하는 컴포넌트와 같은 것을 가르킵니다. 즉 재사용이 가능한 코드를 의미합니다. 웹 컴포넌트를 사용하면 다른 컴포넌트를 사용하는 것과 똑같은 이점을 가질 수 있습니다. 웹 개발자들이 쉽게 코드를 재사용하여 생산성을 높이고 동일한 디자인 요소를 가진 코드를 컴포넌트로 만들어 일관된 사용자 인터페이스를 구현할 수 있게 하는 것이 바로 웹 컴포넌트 ..

개발/JavaScript 2024.05.29

JavaScript V8 엔진과 GC(Garbage Collection)

저는 프로젝트를 진행하면서 과자를 먹곤 하는데요. 과자를 먹다 나온 쓰레기들을 버리러 갈 때 팀원들의 자리에 있는 쓰레기도 함께 모아 가져가며 가비지 콜렉터라는 농담을 했습니다. 그러다가 문득 JavaScript의 Garbage Collection(가비지 콜렉션 이하, GC)은 어떤 방식으로 작동하는지 궁금했습니다. 이전에는 알아보았을 땐 BFS와 같은 탐색을 진행하면서 참조할 수 없는 메모리를 해제한다고 얼렁뚱땅 넘어갔었는데 FE article에서 소개한 Garbage Collection in V8를 읽고 내용을 정리하고 요약해 보았습니다.V8 엔진V8엔진은 구글에서 개발한 오픈 소스 자바스크립트 엔진입니다. 웹 브라우저에서 자바스크립트 코드를 실행하는 데 사용되며, 높은 성능을 가지고 있습니다. 또한..

개발/JavaScript 2024.04.14

Axios를 추상화하여 HTTP 통신을 더욱 쉽게 관리하고 제어하기

자바스크립트와 HTTP 통신에서 가장 많이쓰이는 라이브러리 중 하나인 Axios는 여러 편리한 기능들을 제공하고 있습니다. Axios 여러 편리한 기능을 이용하지 않는다면 자바스크립트의 기본 스펙인 fetch() 함수를 이용하는 것과 다를 바가 없죠. 그렇다면 Axios의 편리한 기능을 한 번 알아 볼까요? 인스턴스(instance)로 모듈화하기 Axios의 편의 기능 중 하나는 새로운 Axios 인스턴스를 만들 수 있다는 것입니다. 여기서 말하는 인스턴스는 객체 지향에서 말하는 인스턴스와 동일합니다. 동일한 설정을 공유해야 하는 경우, 서로 다른 기본 구성을 가진 요청을 만들어야 하는 경우에 Axios를 사용하면 각각의 설정과 구성을 가진 HTTP 클라이언트 인스턴스를 만들어낼 수 있죠. 예를 들어 서..

개발/JavaScript 2024.04.02