자바스크립트 엔진과 런타임 환경

지니·2025년 1월 9일

최근 자바스크립트의 비동기 처리와 동시성에 대해 공부를 하고 있는데, 관련 자료를 읽다 보니 “자바스크립트 런타임 환경”과 “자바스크립트 엔진”에 대한 언급이 자주 등장했다. 마침 자바스크립트 딥다이브를 공부하면서 자바스크립트 코드가 어떻게 동작하는 건지에 대한 궁금증이 생겨서, 이 둘이 자바스크립트의 동작에서 각각 무슨 역할을 하고 있는 건지 정리해 보려고 한다! 🧐


자바스크립트 엔진

자바스크립트 엔진은 자바스크립트 코드를 해석하고 실행하는 소프트웨어를 의미한다. 브라우저나 Node.js 같은 런타임 환경 안에서 사용된다.

주요 엔진들

  • V8: Google에서 개발했고, Google Chrome과 Node.js에서 동작한다.
  • SpiderMonkey: Mozilla에서 개발한 최초의 자바스크립트 엔진으로, Firefox에서 동작한다.
  • JavaScriptCore: iOS나 MacOS 기기의 Safari에서 동작한다.
  • Chakra: Microsoft Edge(구 버전)에서 동작한다. 현재의 Edge는 Chromium 기반 브라우저로 V8 엔진을 사용한다.

브라우저가 서로 다른 엔진으로 자바스크립트 코드를 실행하더라도, 같은 코드에 대해 같은 결과를 가질 수 있도록 자바스크립트 스펙을 표준화해서 ECMAScript를 정하게 되었다.
하지만 내부적인 실행 방식과 최적화 여부는 서로 다르기 때문에 브라우저마다 엔진에 따라 성능 차이가 발생할 수 있다!

엔진의 동작에 대해

엔진의 주요 구성요소로는 메모리 힙과 콜 스택이 있는데, 이 구조 안에서 코드 실행과 데이터가 관리된다.

  • 메모리 힙(Memory Heap)
    • 메모리 할당을 통해 참조 타입의 데이터를 저장한다.

💡 자바스크립트의 변수 식별자
우리가 변수에 값을 할당할 때, 할당하려는 값은 메모리 힙 안의 특정 위치에 저장된다. 그리고 변수는 이 값이 저장된 주소값을 가짐으로써 변수를 참조할 때 할당된 값을 반환하게 된다.

  • 콜 스택(Call Stack)
    • 스택 형태의 자료구조로서, 현재 실행 중인 함수의 정보를 저장해서 함수의 동작을 관리한다.
    • 함수가 호출되는 순서대로 스택에 실행 컨텍스트가 쌓이게 되고, 함수가 종료되면 스택에서 제거된다.

💡 실행 컨텍스트?
코드가 실행될 때 제공할 환경 정보를 갖고 있는 객체이다. 예를 들어 특정 코드 블록에서 사용 가능한 식별자 정보 등이 포함된다.

자바스크립트는 하나의 콜 스택을 갖고 있기 때문에, 한 번에 하나의 일만 할 수 있는 싱글스레드 언어인 것이다.

그럼 런타임 환경은?

한 번에 하나만 할 수 있는데 자바스크립트는 어떻게 동시성을 가질 수 있을까? 런타임 환경까지 이해하고 나니 이 질문이 해소됐다.

위에서 자바스크립트 엔진이 런타임 환경 안에서 사용된다고 언급했다. 예시로 든 모든 엔진 역시 브라우저나 Node.js 안에서 동작하고 있다. 여기서 브라우저, Node.js가 런타임 환경에 해당한다.

런타임 환경은 자바스크립트 엔진이 코드를 실행할 수 있도록 추가적인 환경을 제공한다. 여기에는 이벤트 루프, 콜백 큐, (브라우저 환경의 경우) Web API 등이 포함된다.

런타임 환경 자세히 살펴보기

  • 이벤트 루프(Event Loop): 비동기 작업을 관리하며, 콜백 함수가 콜스택으로 들어가는 시점을 조율.
  • 콜백 큐(Callback Queue): 비동기 작업의 결과를 대기시키는 공간.
  • Web APIs (브라우저 런타임): DOM 조작, HTTP 요청 등 브라우저가 제공하는 기능.
  • Node.js APIs (Node.js 런타임): 파일 시스템, 네트워크 요청 등의 기능.

런타임 환경에서 제공하는 이벤트 루프, 콜백 큐를 통해 자바스크립트는 비동기적으로 작업을 처리할 수 있게 된다. 비동기적으로 실행된 콜백 함수들이 콜백 큐에 들어 있다가, 선입선출 방식에 따라 콜 스택이 비어 있을 때(= 현재 다른 작업이 없을 때) 콜 스택으로 이동해서 실행되게 된다.

콜백 큐는 작업의 성격에 따라 다른 종류로 나눠져 있고(Promise, setTimeOut 등), 각자 우선순위가 다르다. 이때 콜 스택이 비어 있는지 확인하고, 현재 우선순위가 가장 높은 작업을 콜 스택으로 보내 주는 역할을 수행하는 게 이벤트 루프이다.

또한 브라우저와 Node.js는 똑같이 자바스크립트 엔진을 통해 자바스크립트를 실행시킬 수 있지만, 제공하는 환경에는 차이가 있다.

  • 브라우저 런타임: HTML, CSS, 자바스크립트를 실행해 브라우저 화면에 웹 페이지를 렌더링하고자 한다.
  • Node.js 런타임: 브라우저 밖에서 자바스크립트를 실행하고자 한다.

브라우저 환경에서는 Web API를 제공하고, Node.js 환경에서는 이를 사용할 수 없다. 단 Node.js 환경에서도 libuv를 통해 비동기 처리가 가능하며, Node.js는 추가로 내장 파일 시스템을 제공한다.


자바스크립트 엔진이 코드를 실행하는 방식과 런타임 환경이 이를 보조하는 구조를 알아보면서 자바스크립트의 동작 원리를 조금 더 이해할 수 있었다. 이 내용을 바탕으로 다음에는 동시성에 대한 글도 작성해 봐야겠다!

이미지 출처 How JavaScript works

0개의 댓글